This reverts commit 546ff7bbba.
It seems that eo_del() is useful and removing it was creating bugs.
The issue is that the way we defined parents in eo, both the parent and
the programmer share a reference to the object. When we eo_unref() that
reference as the programmer, eo has no way to know it's this specific
reference we are freeing, and not a general one, so in some
circumstances, for example:
eo_ref(child);
eo_unref(child); // trying to delete here
eo_unref(container); // container is deleted here
eo_unref(child); // child already has 0 refs before this point.
We would have an issue with references and objects being freed too soon
and in general, issue with the references.
Having eo_del() solves that, because this one explicitly unparents if
there is a parent, meaning the reference ownership is explicitly taken
by the programmer.
eo_del() is essentially a convenience function around "check if has
parent, and if so unparent, otherwise, unref". Which should be used when
you want to delete an object although it has a parent, and is equivalent
to eo_unref() when it doesn't have one.
The legacy Eio_File factory functions are replaced by an Eo object
called Eo_Job that return promises wrapping the async file operations.
With this commit, the legacy Eio callbacks are replaced by the following
Eo/Promises counterparts :
* Done_Cb -> Promise then success callback
* Error_Cb -> Promise then error callback
* Main_Cb -> Promise progress callback
* Filter_Cb -> Job object event (more below)
Events are used to deliver and get the filter data. To differentiate
between the named and direct versions, they come in "filter,direct" and
"filter,name" versions.
Monitors were wrapped inside a new class Eo_Sentry.
The user creates a sentry object and adds monitoring targets to it,
listening to events on it.
The sentry event info is composed of two strings. The source string
is the path being monitored, i.e. the one passed to eio_sentry_add, and
the trigger string is the path that actually triggered the event, e.g.
a new file created in a monitored directory.
This problem was that because the refcount is now shared between the
parent and the programmer in some cases we would get a double unref. An
example way of triggering it is creating a button and putting it in a
box. The box has a callback registered that when the button is deleted
it would delete itself too. The problem is that the delete callback is
called the button is removed from the box thus causing the box to unref
it again (because of the parent), although the refcount was already
accounted for.
There is another more convoluted scenario that I have yet to fix.
Thanks to raster for reporting.
so... i got this ... callback calls callback calls something calls
callback that deletes the original object at the top so when it comes
back ... things die as the object was destructed. in removing eo_do()
we removed the ref/unrefs that went with it. so this uses the
_EO_API_BEFORE_HOOK and _EO_API_AFTER_HOOK to call exposed "internal"
public functions _eo_real_ref() and _eo_real_unref().
this fixes a new segv i've noticed in several e dialogs where hitting
close does the above via callbacks and closes the window etc.
I thought I compiled, but it seems that @q66 managed to distract
me and I thought wrong and didn't actually. Oh well, fixed now.
Thanks to @zmike for letting me know.
Complex types (i.e. list, array, hash, accessor etc.) now do not require
pointers with them anymore (the pointer is implied) and the same goes for
class handles. Eolian now explicitly disallows creating pointers to these
as well. This is the first part of the work to remove pointers from Eolian
completely, with the goal of simplifying the DSL (higher level) and therefore
making it easier for bindings (as well as easier API usage).
@feature
Apparently you can't cast when initializing static consts, even if
the cast is to the same type. This commit splits the macro used
so we have an additional one that casts and thus works with
eo_override().
This change lets you override the functions of objects so that those
functions will be called instead of the functions of the class. This
lets you change objects on the fly and makes using the delegate pattern
easier (no need to create a class every time anymore).
You can see the newly added tests (in this commit) for usage examples.
@feature
Previously events used to use class name as a prefix and ignored eo_prefix
when specified. This is no longer the case. Events follow eo_prefix by default
now. In order to get around this for classes where this is undesirable, a new
field event_prefix was added which takes priority over eo_prefix. If neither
is specified, class name is used like previously.
@feature
We used to have eo_del() as the mirrored action to eo_add(). No longer,
now you just always eo_unref() to delete an object. This change makes it
so the reference of the parent is shared with the reference the
programmer has. So eo_parent_set(obj, NULL) can free an object, and so
does eo_unref() (even if there is a parent).
This means Eo no longer complains if you have a parent during deletion.
In some build environment, anonymous char delcaration can be interpreted
as "unsigned char". Although lk_init can be only 0, 1 or 2 so there
won't be any unexpected result. This change is just to make static code
analyzer happy.
This commit breaks behaviour!
Re-parenting no longer detaches composite objects, so watch out.
Now you can have an object be a composite object of an object although
it's not its child. This allows widgets to do things like having an
object as the child of a child object while still making it a composite
object to the main object.
With this change, composite objects don't keep a reference to the child,
but instead composite "bonds" are implicitly removed when either the
parent or the child are destructed.
Summary:
object_find is more generic, so other mechanisms can also reuse the
code.
The object itself has to support the function, so there is no need for
eo_isa which would have a negative performance impact.
The base class implementation calls interface_get on the parent, so a
override of the function can just call the super function to continue in
the recursion.
Test Plan: just run the eo test suite
Reviewers: raster, tasn, jpeg
Reviewed By: tasn, jpeg
Subscribers: felipealmeida, netstar, cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D3909
Because we were forcing EWAPI in this macro, one couldn't create a class
that is "static" or even just private or the module. The symbol was
always exposed.
Since in C the attributes of a function are set based on the first
declaration, we don't need to specify any attributes in this macro and
we can just rely on them being specified in the declaration. So for
example, for class "foo":
foo.h:
EWAPI const Eo_Class *foo_class_get(...);
foo.c:
const Eo_Class *foo_class_get(...);
Would give the desired results, a class would be EWAPI. This is already
done automatically for all of the classes using Eolian. Because of the
lack of specifiers, the default visibility will now be the default
visibility based on compiler flags and settings.
Thanks to JP for reporting this issue.
This can potentially (but very unlikely) break things.
This code is an absolute mess. This is the first step towards fixing that.
This cleanup let me find a bug that would have printed errors when using
Eina_Value so I fixed that too.
This was done following a feature request by @raster. There was no real
reason for it not to be an eo function and this gives us more
flexibility.
The reason why this done was to provide a way for classes to do special
things when an object deletion was requested, for example in the case of
Evas, hide the object.
so geneirc data, wrefs, comments and id's are not that common so put
them all into their own memory segment that's allocated separately to
the core object so we only use this memory when needed. we already had
an extension section anyway so it's not new - just using it now for
more of the rarer bits of data. 2 more pointers gone from most objects
anyway and now extension code handling is a bit cleaner.
so memory for class id -> ptrs is mallocs. this means it likely will
be next to other memory malloced. which means overrunning memory
someone mallocs could walk into the class table and corrupt it. we put
eo ids in mmaped regions to avoid this if possible in case of buggy
code. let's do it for classes too.
this also now allocs in larger chunks. for mmap its in page chunks
(which can hold either 1024 or 512 classes depending on 32 or 64bit).
reallocs still work if mmap is not there and we do them in chunks of
128 classes (it seems that we start at about 70 or so classes atm when
elm_test starts and it grows to ~100 or let's do 128 as that's pretty
much our base as a power of 2 and we now dont realloc much).
base class objects will ask their parent object to get the loop. this
means it recurses all objects regardless of type until it finds an
object that returns a proper loop object - eg a loop object returns
itself, a window, gfx/ui object returns the mainloop object etc. etc.
@feature
The idea is that when you are processing those events from within
they won't call twice any of the event until all of them are processed
at least once (Or one of them did return EINA_FALSE).
this finds child objects by walking the child tree searching children
by using the search string which can be name, class:name and both
class and name can also be a glob.
@feature
eina value would allow any value to be attached to an eo object and
also be freed nicely too. this would allow any generic data to go
there without overloading a void * that us c coders love to abuse.
@feature
also useful for debugging and more. this also makes both name/id and
comment an extension blob of ram so objects dont keep growing
boundlessly in memory usage/size
@feature
also evas objects have names too, so add this as this was discussed
and now the feature is in. there is nothing to find objects by name
yet. that's more api's and features to add after this.
@feature
this adds eo_key_obj_set/get/del() like with data but for object
handles so the obj is ref'd as long as the key and parent obj exists
and then unreffed on deletion. it also tracks deletion of reffed
objects like weak refs and then removes the key automatically.
@feature
Modify the way hooks are defined and used by promise generation in
Eolian in the Eo API.
Instead of passing macro names as parameters to EO_FUNC_BODY macros,
just re-define the actual hooks when it is needed.
For windows, EAPI needs to be redefined as dllexport/dllimport.
Since we marked all EO APIs as weak, we had two different EAPI
macros: EAPI and EWAPI. Unfortunately, EWAPI was never redefined
(only declared inside Eo.h).
See also a1a506e13e.
See T3423. Thanks @vtorri for the report.
While eolian-gen was generating EWAPI (weak) class_get()
symbol declarations, they were implemented as EAPI (strong).
Not sure if this mismatch had any significant effect.
This patch tries to address T3423 (windows build).
The mismatch between EAPI and EWAPI might be the problem.
Add two parameters for macros that generate API functions in Eo so
that the generation can be customized with macros used by Eolian.
Signed-off-by: Cedric Bail <cedric@osg.samsung.com>
I'm reverting this because according to jpeg it was possibly fixed in
5284b62e93.
I reverted this patch after his fix and followed his reproduction cases
and it seems that his second patch does indeed fix this issue so this
patch is no longer needed.
This reverts commit 0862b9d083.
The function call resolve cache may be broken after an eo
shutdown + init cycle, leading to calls to invalid functions.
This adds an static uint for each and every single EO API
entry point, as well as an extra if() check.
Now I'm not sure if the previous commit 0862b9d083 is
still necessary.
It seems that calling a @class function with an EO object
(that was not the required Eo_Class) lead to a situation
where func->func was NULL. And that meant a crash after
call_resolve.
The proper fix is to properly call a @class function with a
class object.
This marks all EOAPI functions with GCC weak attribute.
This allows two things:
- replace functions
- link at runtime and check if functions exist
The purpose of this patch is to exploit these two features
of weak symbols. The first goal is to allow applications
to build binaries against later versions and run on earlier
versions of EFL without any run-time link error. Those errors
simply prevent applications to even start if they were using
any function that's not present in the old version of EFL.
Now all that needs to be done on the application side is to
do either of:
- if (efl_version > xx) { call_weak_symbol() }
- if (call_weak_symbol) { call_weak_symbol() }
In the future, we can also imagine providing a compatibility
library that would replace EFL's internal APIs with a newer
version. This would let apps use new EFLs on platforms that
don't update fast enough.
I am now pushing this patch as an experiment to see what breaks,
but I expect no problem.
@feature
The current eo_add uses a (very useful) gcc extension that is only
available in gcc compatible compilers (e.g clang). Until this commit we
just temporarily ignored this fact. This adds a fallback implementation that
can be used interchangeably with the non portable one. This means that the
same binary can call either at any point in time and the code will work.
Breaks ABI.
It was temporarily eoid, change it to eo_self which is more
descriptive. In this process I also made it a macro to prepare
for the proposed changes on the ML for the fallback implementation
for compilers that don't support the compound statements returning
values gcc extension.
I found a way to keep eo_add() the way it was and gracefully degrade to
a portable (but not as fast) solution for compilers that don't support
the compound macros returning a value gnu extension: ({int a; a;}).
I'm reverting these changes now, and I'll introduce the fallback as soon
as I can.
This reverts commit b85bb37183.
Reverting this at Felipe's request following my email. There are many
things I strongly object to in this commit. I've touched the surface of
those on the ML (which doesn't work at the moment), though we need to
better discuss it.
The gist:
1. dlsym is a really bad hack that is not even needed.
2. I don't see why eo should even be aware of promises. It's not aware
of list, hash and etc.
3. The eolian changes were done wrong.
This should have been discussed and consulted before done, even if only
because of the amount of hacks it includes and the cross-domain (ecore,
eo and eolian) nature of it.
This reverts commit f9ba80ab33.
Imagine this. You have an object. You pass this object handle as a
message to another thread. Let's say it's not a UI object, so
something you might expect to be able to be accessed from multiple
threads. In order to keep the object alive you eo_ref() it when
placing the message on a queue and eo_unref() it once the message is
"done" in the other thread. If the original sender unref()ed the
object before the message is done, then the object will be destroyed
in the reciever thread. This is bad for objects "expecting" not to be
destroyed outside their owning thread.
This allows thius situation to be fixed. A constructor in a class of
an object can set up a delete interceptor. For example if we have a
"loop ownership" class you multi-ple-inherit from/use as a mixin. This
class will set up the interceptor to ensure that on destruction if
pthread_self() != owning loop thread id, then add object to "delete
me" queue on the owning loop and wake it up. the owning loop thread
will wake up and then process this queue and delete the queued objects
nicely and safely within the "owning context".
This can also be used in this same manner to defer deletion within a
loop "until later" in the same delete_me queue.
You can even use this as a caching mechanism for objects to prevernt
their actual destruction and instead place them in a cached area to be
picked from at a later date.
The uses are many for this and this is a basic building block for
future EFL features like generic messages where a message payload
could be an eo object and thus the above loop onwership issue can
happen and needs fixing.
This adds APIs, implementation, documentation (doxy reference) and tests.
@feature
Add a promise object that allows Eolian interface to include promises
as a way to have asynchronous value return and composibility.
The usage is like this in a .eo file:
class Foo {
methods {
bar {
params {
promise: Promise<int>;
}
}
}
}
Which will create the following API interface:
void foo_bar(Ecore_Promise** promise);
and the equivalent declaration for implementation.
However, the API function will instantiate the Promise for the
user and the implementer of the class.
Mostly unused vars following the removal of eo_do_ret().
However, there are some cases where the migration script got some things
wrong, and I had to manually fix them.
I just ran my script (email to follow) to migrate all of the EFL
automatically. This commit is *only* the automatic conversion, so it can
be easily reverted and re-run.
The syntax is described in: https://phab.enlightenment.org/w/eo/
Summary:
eo_do(obj, a_set(1)) -> a_set(obj, 1)
eo_do_super(obj, CLASS, a_set(1)) -> a_set(eo_super(obj, CLASS), 1)
eo_do_*_ret() set of functions are no longer needed.
This is the first step, the next step would be to also fix up eo_add()
which currently still uses the old syntax and is not 100% portable.
@feature
Change the Eo event callback signature to what suggested by Marcel
Hollerbach in the ML (Thread: EFL interface change - Animator).
This changes the signature of callbacks from
Eina_Bool cb(void *data, Eo *obj const Eo_Event_Description *desc, void *event_info)
to
Eina_Bool cb(void *data, const Eo_Event *event)
Where Eo_Event is a structure that holds these parameters.
This makes it less annoying to not use parameters (you end up using
EINA_UNUSED less), and allows for future extensions to callback
parameters.
@feature
Until now it wasn't allowed/possible to init (eo_init) eo after it has
been shut down (eo_shutdown). This commit fixes that, so now that is
fully legal to have as many init/shutdown cycles as you want.
There was a previous workaround for this issue:
e47edc250d.
This should allow more flexibility when using the EFL in loadable
modules and in various other scenarios.
The problem is that the class_get() functions cache the previously
created class for efficiency, but the class is freed if eo is shut down,
so the cached pointer is actually invalid.
The solution to the problem was to maintain a generation count
(incremented every time we shut down eo), and compare that to a locally
saved version in class_get(). If they don't match, recreate the class,
as it has already been freed.
@feature
This commit was a workaround to let us shutdown and then init eo without
any issues. It leaks and it's wrong. This will properly be fixed in the
next commit.
This reverts commit e47edc250d.
Leave variables named Klass so it behaves with syntax highlighting and doesn't confuse programmers. However when Erroring, the message should be spelled correctly with "Class".
This is not really needed, I just did it to make it easier for coverity
(and future static analysers) to understand that the class id doesn't
need to be accessed with a lock.
CID1341854
Currently, eo_shutdown can't work.
Every Eo_Class ID is stored inside its class_get() function as a
static variable. This means any call to class_get() after eo_shutdown()
(even if eo_init was done properly) will lead to using an invalid ref
for the class id. In other words, the class is not valid anymore,
and objects can't be created.
Resetting the pointer to NULL would be possible, if we passed it
during the class creation. But this would lead to potential crashes
if a class was created from a now dlclosed library.
The only solution I can envision here is to check that class_get
actually returns a valid ref with the right class name. Most likely
the performance impact is not acceptable.
This fixes make check for me (with systemd module for ecore).
Useful for GDB: break on this function when things go wrong.
Similar to eina_safety.
I guess we could set some Eina_Error and maybe even have error
callbacks for easier application debugging. Later.
Coverity CID1339783 says that we have a potential resource leak here.
'cb' gets allocated via calloc, but is not freed if we end up
returning here
@fix
Signed-off-by: Chris Michael <cpmichael@osg.samsung.com>
To configure efl sources with bindings to use in nodejs add ––with-js=nodejs in configure flags to generate node files
$ configure --with-js=nodejs
and compile normally with:
$ make
$ make install
To use, you have to require efl:
efl = require('efl')
The bindings is divided in two parts: generated and manually
written. The generation uses the Eolian library for parsing Eo files
and generate C++ code that is compiled against V8 interpreter library
to create a efl.node file that can be required in a node.js instance.
@feature
This reverts commit 4b116627c2.
This can't be done, because the freeze state can change from within the
callbacks so you need to check if events are frozen every time.
This is faster in most cases, and to be honest, should be much faster
than it is. I don't understand why there's no better directive to mark a
variable as *really* important thread storage that is used all the time.
We don't really need the eo_id most of the time, and when we do, it's
very easy to get it. It's better if we just don't save the eo_id on the
stack, and just save if it's an object or a class instead.
It seems that the idea behind that optimisation, is to save object data
fetching when calling functions implemented by the object's class inside
functions implemented by the object's class. This should be rare enough
not to worth the upkeep, memory reads and memory writes, especially
since for all cases apart of mixins (for which this optimisation won't
work for anyway), the upkeep is more costly than fetching the data
again.
with eo id indirection on, a nul object is silently ignored as anok
error case (like free(NULL)). but if you turne eoid off in build its
all complaints to here and the black stump. fix this by making the eo
id "off" path match eo id on by making null objects silent.
@fix
removing the klass member meant removing hooks and keeping cache small
but that meant not using it. this meand if the object is not an obj...
i removed the:
call->obj = _eo_class_id_get(call->klass);
line - seemed harmless/pointless. apparently not. so put it back but
use the klass there in local vars and not in call as it's not there
(and not needed).
fix.
we pass both the callcache and the op id - both are static and filled
in at runtime, so merge them into the same struct. this should lead to
better alignment/padding with the offset array and the next slot and
op fields, probably saving about 4-8 bytes of rame per method with no
downsides. also pass in only cache ptr, not both cache ptr and opid -
less passing of stuff around and should be better.
so. clang is wrong. end of story. it complains that i should add
braces to:
static Eo_Call_Cache ___callcache = { 0 };
WRONG. that is correct c99. 100%. you can add more {}'s and init every
field separately like {{0},{0},{0}} etc. or make it 1 or any value -
it doesn't matter... clang complains. clang is wrong. plain and
simple. this warning should just never exist. it is pointless.
but... peolpe won't shut up about clang warnings until i "fool" clang
into being silent by assuming the default 0 value of static storage.
this silences clang
BEWARE! this breaks eo ABI. _eo_call_resolve and _eo_data_scope_get
are 2 of the biggest cpu users in eo. they easily consume like 10-15%
cpu between them on tests that drive a lot of api - like simply
scrolling a genlist around. this is a lot of overhead for efl. this
fixes that to make them far leaner. In fact this got an overall 10%
cpu usage drop and that includes all of the actual rendering, and code
work, so this would drop the eo overhead of these functions incredibly
low. using this much cpu just on doing call marshalling is a bug and
thus - this is a fix, but ... with an abi break to boot. more abi
breaks may happen before release to try and get them all in this
release so we don't have to do them again later.
note i actually tested 4, 3, 2, and 1 cache slots, and 1 was the
fastest. 2 was very close behind and then it got worse. all were
better than with no cache though.
benchmark test method:
export ELM_ENGINE=gl
export ELM_TEST_AUTOBOUNCE=1
while [ 1 ]; do sync; sync; sync; time elementary_test -to genlist;
sleep 1; done
take the 2nd to the 8th results (7 runs) and total up system and user
time. copmpare this to the same without the cache. with the cache cpu
time used is 90.3% of the cpu time used without - thus a win. at least
in my tests.
@fix
so we do a bit of error handling like does a stack fail to allocate,
does setting the tls var fail, have the stack frames been nulled or
not allocated, etc. - these acutally cost every call because they mean
some extra compare and branches, but ore because they cause a lot fo
extra code to be generated, thus polluting instruction cache with code
and cacheline fetches of code that we rarely take - if ever.
every if () and DBG, ERR etc. does cost something. in really hotpath
code like this, i think it's best we realize that these checks will
basically never be triggered, because if a stack fails to grow... we
likely alreayd blew our REAL stack for the C/C++ side and that can't
allocate anymore and has already just crashed (no magic message there -
just segv). so in this case i think this checking is pointless and
just costs us rather than gets us anything.
This causes a significant speed up (around 10% here) and is definitely
worth it. The way it's done lets the compiler cache the value across
different eo_do calls, and across the parts of eo_do. Start and end.
This breaks ABI.
This may look like an insignificant change, but it doubles the speed of
this function, and since this function is called so often, it actually
improves my benchmarks by around 8%.
This breaks ABI in a harmless way, and it will give us the ability to
drastically improve Eo in the future without breaking ABI again, thus
allowing us to declare Eo stable for this release if we choose to.
My previous patch to this piece of code
(37f84b7e96), caused a significant
performance regression. This is such a hot path, that even accessing the
strings when we don't have to slows things down drastically. It makes
more sense to just store it in the structure.
This commit breaks ABI (though most people probably won't even need to
recompile anything else because of the memory layout).
It was discussed on IRC and was decided this is a big enough issue to
warrant a fix during the freeze.
@fix
We use function names instead of function pointers of Windows, because
of dll import/export issues (more in a comment in eo.c). Before this
commit we were comparing the pointers to the strings instead of the
content in some of the places, which caused op desc lookup not to work.
This fixes that.
Thanks to vtorri for his assistance.
@fix
This removes code that became dead in commit:
389c6d35f2
The commit doesn't explain why we don't shrink or grow when using mmap,
but this is how it is. No reason to keep old code there.
CID 1240224
@fix
Commit 37f84b7e96 introduced a few changes
to the callback matching mechanism that made it so sometimes callbacks
would be triggered for the wrong events. The problem was there because
of the support for legacy events that forces to do string comparison
instead of the usual pointer comparison. We should only do string
comparison when we are certain one of the callbacks is a legacy
generated one.
Regression tests will follow tomorrow. Way too late here for that.
Thanks to cedric for reporting.
As described by Carsten in his email to edev ML titled:
"[E-devel] eo stability - i think we need to postpone that"
with the switch to Eo2 we significantly increased our usage of RW memory
pages, and thus significantly increased our memory usage when running
multiple applications.
The problem was that during the migration to Eo2 the op id cache and the
op description arrays were merged, causing the op description arrays to
no longer be RO. This patch enables users of Eo (mainly Eolian) to
declare those arrays as const (RO) again, saving that memory.
There might be performance implications with this patch. I had to remove
the op desc array sorting, and I used a hash table for the lookup. I
think the op desc sorting doesn't really affect performance because that
array is seldom accessed and is usually pretty short. The hash table
is not a problem either, because it's behind the scenes, so it can be
changed to a more efficient data structure if the hash table is not good
enough. The hash table itself is also rarely accessed, so it's mostly
about memory.
Please keep an eye for any bugs, performance or excessive memory usage.
I believe this should be better on all fronts.
This commit *BREAKS ABI*.
@fix
The old naming is inconsistent with the rest of the EFL. This fixes that.
Since we are already breaking ABI (and possibly API), we should fix this too.
This hasn't been used for a while. Since we are going to break Eo a bit anyway
it's a good opportunity to drop this.
This may cause a slight performance issues with legacy events, such as
smart callbacks. This shouldn't really be a problem as we've migrated away from
them. If it does, we need to migrate the remaining parts. Only relevant
for callbacks that are added before the classes are created, which
shouldn't be possible except for smart, only for old evas callbacks.
Scenario:
- Same signal/function/data registered twice on e.g mouse_down
- On mouse_down, register mouse_move and mouse_up
- On mouse_up, unregister mouse_move
Result: mouse_move still invoked after mouse_up
Reason:
- When the mouse_move callback deletion is required, the cb is
flagged as deleted but is not freed as walking_list blocks.
- When the second (and same) has to be deleted, it will try to delete
the first again because the delete_me flag is not checked.
This patch fixes it by checking the delete_me flag when determining the
candidate.
@fix
This should not happen. Objects with parents must have their parents
unset before they reach refcount == 0. That's because the parent is the
one holding the refcount. This means that if we get to the destructor
(object is deleted) while a parent is still set, we have an error
scenario.
After this change, parent_set assigns a ref, so for example:
obj = eo_add(CLASS, parent); /* Ref is 1 */
eo_do(obj, eo_parent_set(parent2)); /* Ref is 1 */
eo_ref(obj); /* Ref is 2 */
eo_do(obj, eo_parent_set(NULL)); /* Ref is 1, giving the ref to NULL */
eo_do(obj, eo_parent_set(parent)); /* Ref is 1 */
This is following a discussion on the ML about commit
8689d54471.
@feature
optimization
xrefs keep lists of objects references. children are already in a list.
why keep both? lots of extra memory used for no value when debug is on
(pretty much most of the time).
this follows on from cbc1a217bf as this
code was correct, but was then causing bugs due to children staying in
their parent lists. this should never have happened and this is really
bad. this fixes this and ensures children on destruction are gone from
their parent lists.
@fix
it is possible that a destructor/parent_set override or function could
go modifying the children list of objects in a parent, this the
EINA_LIST_FREE may actually miss objects in the process since within
the "free" func the list may have been altered etc.
@fix
@fix
XXX: Given EFL usage of objects, construction is a perfectly valid thing
to do. we shouldn't complain about it as handling a NULL obj creation is
the job of the caller. a perfect example here is ecore_con and ecore_ipc
where you create a con or ipc obj then set up type/destination/port and
the finalize of the constructor does the actual connect and thus this
fails or succeeds based on if service is there.
until there is a better solution - don't complain here.
This is heavily based on a patch by Vincent Torri. I just refactored it
a bit so it doesn't break ABI on Linux, only on Windows (where it was
broken anyway).
This patch changes things so on Windows, functions are looked up only
based on their name. Because of the indirection (and export/import
tables) windows does, this is the only reasonable way to make it work.
You should always use curly brackets. Especially when the inside statement
has its own curlys. This can be confusing and has already lead to bugs in
many projects.
This was not really useful and against the Eolian guidelines.
While I promised I won't break things until the 27th, I was ill
(still am), so I'm giving myself a 1 day pass. :P
While unrefing twice works, it's cleaner to unref the ref we
have and delete normally. It will handle parnet detachments in
a nicer way, and is just more correct.
This is another cleanup in perparation for the Eo stable release.
This is no longer needed thanks to the proper error reporting with
eo_constructor()'s new return value.
The finalizer change cleans it up a bit so it catches more cases/issues.
This also means that the finalizer cleans up the object in all cases,
and not only some.
@feature.
From now on, constructors should return a value, usually the object
being worked on, or NULL (if the constructor failed). This can also
be used for implementing singletons, by just always returning the same
object from the constructor.
This is one of the final steps towards stabilizing Eo.
@feature
Instead of "@in type name;" we now use "@in name: type;". This change
is done because of consistency with the rest of Eolian; pretty much
every other part of Eolian syntax uses the latter form.
This is a big breaking change in the .eo format, so please update your
.eo files accordingly and compile Elementary together with the EFL.
@feature
This is a convenience macro to be used by the common pattern of getting
a part and then immediately calling functions on it. For example,
without this macro, you'd have to write code like:
Eo *part;
eo_do(obj, part = efl_part_name_get("partname"));
eo_do(part, a_set(7));
while using the helper function trims it to:
eo_do_part(obj, efl_part_name_get("partname"), a_set(7));
@feature
Remove it from the constructors section.
This was wrong. This place is for functions that are allowed to be
passed to eo_add() and should be used by bindings to create
constructors.
This is wrong for both cases, as this should always be called, not
optional.
Also remove the redundant legacy: null.
This is following a last review and a discussion on IRC. Eo has been
stable (apart of a decision a few months ago to support more compilers)
for a long while. Developers are already using it for a while, and it's
stupid to break it for them anyway, so we might as well make this
promise now. There are no plans to change it anymore, and it's been
heavily used and tested throughout the EFL for a few releases now.
I'm tagging it as a feature, although it's not, I'm doing it for the
automatic changelog generation. :)
@feature.
As discussed on IRC and ML. We are in a feature freeze phase, and this
patch is not essential. Furthermore, this patch was never discussed.
This reverts commit 537c7fe9e3.
Summary: Had a chat with raster to understand the behavior of these two functions in the IRC. Thought it might be helpful if added in the documentation itself. So updated it accordingly.
Reviewers: cedric
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D2083
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This affects eo_do() and eo_add() that used to use the ({}) GCCism.
Following a discussion with Peter de Ridder after my talk at FOSDEM,
we've decided to reopen the GCCism (works with other gcc compatible
compilers like clang and intelc) discussion, and after a bit of back and
forth it was decided to make things more portable, at the cost of ease
of use.
For example:
if (eo_do(obj, visible_get()))
is no longer allowed, the portable alternative
Eina_Bool tmp;
if (eo_do_ret(obj, tmp, visible_get()))
is to be used instead.
However:
eo_do(obj, a = a_get(), b = b_get(), bool_set(!bool_get))
are still allowed and OK.
eo_do(obj, if (a_get()) return;);
is no longer allowed, but:
eo_do(obj, if (a_get()) something());
is still allowed.
For clarity, this commit only incorporates the Eo changes, and not the
EFL changes to make the efl conform with this change.
Thanks again to Peter de Ridder for triggering this important discussion
which led to this change.
The header.id was masked before using it as index in the _eo_classes
array and was not unmasked when used.
It hasn't caused segfault (by sheer luck) but was wrong.
@fix
Before this fix, when a deletion was invoked twice on an object, a
wrong message ("...You wrongly call eo_unref() within a destructor...")
was printed. This was caused by the del_triggered flag that was not
resetted when the destruction finished.
This patch fixes this behavior by printing the right message on a double
deletion.
So I don't really understand why the code was not there before, but it resulted
in my experiment of making a combobox for elementary just impossible. Now it
work at least.
In some cases, invalid object ids (e.g 0x1) would pass validation and
represent completely different objects (0x80...01). This happened because
we weren't properly checking a given object id is actually an object id.
@fix.
For some reason, they were normal functions instead of eo functions,
which makes them harder to bind, less safe, and just wrong.
This commit fixes that.
Now it's more clear and consistent. This commit complements the previous
eo_add commit (a7560dbc61).
Now eo_add should be matched with eo_del
eo_ref with eo_unref
eo_add_ref with eo_unref + eo_del
Essentially, the change is that if you have the ref to an object, you
need to unref it. Thus making ref/unref unneeded for most people who use
things (carefully) in c. If however, you would like to delete an object
previously created by you, you should eo_del (counter-part to eo_add).
It's still recommended you ref/unref when dealing with objects in
scopes, as you can't know when an object might just get deleted as a
by-product of another call.
This fixes an issue found by JackDanielZ.
Before this change eo_add() used to create an object with 1 ref, and if
the object had a parent, a second ref.
Now, eo_add() always returns an object with 1 ref, and eo_add_ref()
preserves the old behaviour (for bindings).
eo_unref now un-parents if refcount is 0, and eo_del() is an alias for
eo_unref (will change to be a way to ensure an object is dead and goes
to zombie-land even if still refed).
This moves the mainloop check inside the function. There was never need
for it to be in client code (i.e a header/macro).
This is better suited inside eo_do_start because this is a macro some
bindings have to re-implement, and we definitely don't want it to be any
more complicated than it has to be.
This breaks ABI and makes elm 1.12 depend on efl 1.11. This is not an issue
as because of eolian and interfaces it's already the case.
eina_tls_get is really slow, having a fast path for the main loop does really
help us right now. It is also unlikely that slowing down a little bit the use
of eo in thread is going to have any impact on application speed any time soon.
I win a +10% on expedite benchmark compared to without.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This enables checking if an object is being created, or has already been
finalized. This is useful in functions that you want to allow
only during the creation phase (i.e inside the eo_add()).
Comp objects are rare, and since we allow using classes as interfaces,
we end up allocating a lot of memory for something we don't even use.
That's why it was a linked list in the first place, and that's why it
should remain a list.
This is almost a complete revert. I reverted the code itself, and the
intent (use of array instead of list), but not the tests, or the new
return value added to comp_detach, which is useful.
This reverts commit ef09ef7489.
This function lets you hook at the end of eo_add and override it for a
class. This is essentially the first step towards killing custom
constructors. Instead of having a custom constructor, you should just
do:
eo_add(CLASS, parent, a_set(3), b_set("eou"));
eo_constructor is called at the beginning for pre-init things.
eo_finalize is called at the end, for actually finalizing and doing
things. This cleans up the API and possibly saves a lot of things that
would have been stupid and slow in the past, like loading an elm widget
with an existing theme, and then changing the theme.
** This breaks Eo ABI, please recompile elementary and everything else that
creates eo objects.
@feature
Match function names when the API pointer is out of range.
Reviewed by TAsn and modified according to his comments :)
Differential Revision: https://phab.enlightenment.org/D876
We check _current_table for NULL, and then populate it (it's a global)
through another function, but we don't really check it's not NULL before
using it, we just assume because of an indirect other variable.
This confused coveritiy, can confuse humans too, and in general risky
(if something changes).
CID 1039419
Coverity found the issue, but it's an issue we've already fixed in the
past. I don't know how it got lost, but it seems like someone did a bad
merge. Probably when migrating to Eo2.
This reverts commit 831c20464d.
this fixes and eo2 problem where when callstack grows (or shrinks)
and realloc nas to relocate memory, the frame ptrs like fptr become
invalid and all sorts of hell ensues.
this uses mmap so blowing the stack will segv, not scribble over
memory, also its separated from malloc heap, and now big enough to not
need to size ... ever (1024 entries).
due to recent changes a lot of objects are now NULL (correctly) and eo
complains on access of them. it's simply too noisy adding too many
if's all through code, so let's just make eo be sensible here.
It's now completely valid to do:
a = eo_do(obj, a_get());
or:
b = eo_do(obj, a_set(1), b_get());
Also, the default return value for eo2 functions is now also returned
when the object is invalid, not just when the object does not match
class.
It's a small refactor that fixed both issues at once.
@feature
@fix