we do not check any of success, failure or progress, so we must check
if they are valid before calling.
This fixed a bug in efl_net_dialer_tcp where it uses a null failure
cb and was SEGV.
Efl_Future actually work with weak reference. So you do not need to
set things to NULL, but you actually need to register the memory location
of the future with efl_future_use.
This would have forced who ever used future,none signal to manually
filter out event triggered by all the future beeing fullfiled and
disconnecting once they receive a value or are marked failed.
As discussed in the mailing list, many people will use worker threads
to execute blocking syscalls and mandating ecore_thread_check() for
voluntary preemption reduces the ecore_thread usefulness a lot.
A clear example is ecore_con usage of connect() and getaddrinfo() in
threads. If the connect timeout expires, the thread will be cancelled,
but it was blocked on syscalls and they will hang around for long
time. If the application exits, ecore will print an error saying it
can SEGV.
Then enable access to pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)
via eina_thread_cancellable_set(EINA_TRUE), to pthread_cancel() via
eina_thread_cancel(), to pthread_cleanup_push()/pthread_cleanup_pop()
via EINA_THREAD_CLEANUP_PUSH()/EINA_THREAD_CLEANUP_POP() and so on.
Ecore threads will enforce non-cancellable threads on its own code,
but the user may decide to enable that and allow cancellation, that's
not an issue since ecore_thread now plays well and use cleanup
functions.
Ecore con connect/resolve make use of that and enable cancellable
state, efl_net_dialer_tcp benefits a lot from that.
A good comparison of the benefit is to run:
./src/examples/ecore/efl_io_copier_example tcp://google.com:1234 :stdout:
before and after. It will timeout after 30s and with this patch the
thread is gone, no ecore error is printed about possible SEGV.
This moved all the eoid tables, eoid lookup caches, generation count
information ad eo_isa cache into a TLS segment of memory that is
thread private. There is also a shared domain for EO objects that all
threads can access, but it has an added cost of a lock. This means
objects accessed outside the thread they were created in cannot be
accessed by another thread unless they are adopted in temporarily, or
create4d with the shared domain active at the time of creation. child
objects will use their parent object domain if created with a parent
object passed in. If you were accessing EO (EFL) objects across threads
before then this will actually now cause your code to fail as it was
invalid before to do this as no actual objects were threadsafe in EFL,
so this will force things to "fail early".
ecore_thread_main_loop_begin() and end() still work as this uses the
eo domain adoption features to temporarily adopt a domain during this
section and then return it when done.
This returns speed back to eo brining the overhead in my tests of
lookup for the elm genlist autobounce test in elementary from about
5-7% down to 2.5-2.6%. A steep drop.
This does not mean everything is perfect. Still to do are:
1. Tests in the test suite
2. Some API's to help for sending objects from thread to thread
3. Make the eo call cache TLS data to make it also safe
4. Look at other locks in eo and probably move them to TLS data
5. Make eo resolve and call wrappers that call the real method func do
recursive mutex wrapping of the given object IF it is a shared object
to provide threadsafety transparently for shared objects (but adding
some overhead as a result)
6. Test test est, and that is why this commit is going in now for wider
testing
7. Decide how to make this work with sending IPC (between threads)
8. Deciding what makes an object sendable (a sendable property in base?)
9. Deciding what makes an object shareable (a sharable property in base?)
It has been discussed on the ML (thread: "[RFC] rename efl_self") and
IRC, and has been decided we should rename it to this in order to avoid
confusion with the already established meaning of self which is very
similar to what we were using it for, but didn't have complete overlap.
Kudos to Marcel Hollerbach for initiating the discussion and
fighting for it until he convinced a significant mass. :)
This commit breaks API, and depending on compiler potentially ABI.
@feature
while in a job we do not have the safety of eo holding us alive and
when we call back the user, he may have deleted the object, releasing
both the object and its private data that we're using.
then keep an extra reference, call the methods and release it.
Efl.Object.event_callback_call no longer calls legacy smart callbacks;
calling only event callbacks registered with the given event description
pointer.
Create the method Efl.Object.event_callback_legacy_call to inherit the old
behavior from Efl.Object.event_callback_call, calling both Efl.Object events
and legacy smart callbacks.
Update all other files accordingly in order to still supply legacy
callbacks while they are necessary.
These interfaces allows generic operations on objects that can store
or provide data, such as a file or a buffer.
With well defined interfaces and events we can create code such as
Efl.Io.Copier, that will link a source with a destination and
progressively copy data as they appear.
it was silently ignoring the parent, which led me to hours trying to
investigate why my code wasn't working just to realize my parent
wasn't being assigned and refcounts were screwed.
This places the following behind beta:
- efl_quicklaunch_fallback
- efl_build_version_set
I don't think EFL_MAIN would have worked without BETA API support,
so no need to expose those for now.
@fix
in theory another libc call could overwrite errno between select
exiting and errno being used for errors. be paranoid. i know of no
real bug that this causes though.
i've fixed almost all the eina init/shutdown pairs to do the right
thing now... except one (ecore_shutdown) with comment inline where
eo_shutdown is not called. if this is called we are in crash land.
this needs further inspection.
ecore_timer_del() checks a flag "inside_call" that can be
set before calling the timer cb... but it was never reset
to 0. So, all legacy timers would keep on ticking forever
and ever, until they return CANCEL.
Anyway, I find the distinction between eo_del and
ecore_timer_del very troubling. eo_del() should work
on a legacy timer. Ping @cedric. Maybe override eo_del()?
Fixes T3898
The original idea behind knowing the app's version of EFL is not
a great story. It comes from the fact that some bugs exist in
earlier versions of EFL, and some things need to be fixed. But
those fixes may break behaviour for older apps. This patch is
opening the way to the slippery slope of bug compatibility.
Unfortunately this is a requirement if we want to be able to move
forward and not break apps when we fix bugs (behaviour or ABI).
I hope we will not need to implement too many (if any) workaround
such issues. For now, this will only be used as debugging info.
EFL_MAIN() and ELM_MAIN() will both set the app's EFL version
automatically at startup time. Some internal helpers can be added
later to check how the app build-time and run-time version of
EFL differ.
@feature
Note: this is both @class and @property. Hope that's ok for
all bindings.
This returns same as ecore_main_loop_get() (which now uses the eo
api instead).
Ping @cedric (so he can check this patch).
evas 3d examples would always exit on a double free, since
EINA_INLIST_FREE was misused. Not surprising considering
it's different from EINA_LIST_FREE but has a similar name.
On Solaris, this header is necessary for finite(). Instead of including it
if the sun compiler is used, include it if it exists. This fixes a warning
if gcc is used on Solaris
Clockid_t should be used as an opaque type. Some platform might want
to (and even do, e.g. DragonFlyBSD) declare clockid_t as an unsigned.
On such platform, testing the sign of clockid_t is never false, and
assigning it a negative value is an UB, which makes this code unlikely to
work as intended. Fixes black window on dragonfly!
Thanks to gcc for spotting this.
CC lib/ecore/lib_ecore_libecore_la-ecore_time.lo
In file included from ../src/lib/eina/Eina.h:215:0,
from lib/ecore/Ecore.h:304,
from lib/ecore/ecore_time.c:18:
lib/ecore/ecore_time.c: In function 'ecore_time_get':
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Turns out there is no PRI?SIGATOMIC in the C99 standard. Work around
that by deducing the effective integer type by comparing the
SIG_ATOMIC_MAX with integers *MAX.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
The bug came from the fact we need to handle the destruction of the
main loop which destroy the underlying timer. The event handler that
catch the destruction of the timer can not make the difference between
eo_del call from the timeout code and eo_del from the main loop
destruction. By removing the event handler, the double free is properly
avoided.
As we add more object in the main loop, they can't live in the top
namespace as they make little sense there (Efl.Fd !). For coherence,
everyone should in the loop namespace, so move timer there.
Now when dealing with pointer types, we will not get pointer to
pointer semantics in callbacks and eina_promise_owner_value_set
for Eina_Promise.
It will work as expected:
Eina_Promise_Owner* promise = eina_promise_add();
void* p = malloc(sizeof(T));
eina_promise_owner_value_set(promise, p, &free);
This lets me narrow down the remaining cases of pointers across the EFL.
The void pointers will later need to be reevaluated on per-case basis and
replaced appropriately where possible/feasible.
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.
this is an args event. right now we don't use it, but this should be
done by some of the setup/init of an app and then produce an args
event. the idea would be that this can be used by single-instance apps
like web browsers, terminology to treat launch as an event.
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
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.
So ecore main loop does restart everything with an main loop shutdown
and init when it detect a bad fd. This can happen if you del a fd after
you have destroyed it. Something terminology is doing (and should be
legal), but that then ended up with a main loop with no event handler
registered and the process was looking like stuck with nothing happening.
This allow you to monitor fd and get notification using Eo events. I
have not implemented the buffered read as used by X. I think that if
this is useful, we should just do another class to handle bufferred fd.
This reverts commit a13570c17c.
This doesn't really fix the problem which is hidden by eo capability to not
crash on bad unref. With legacy API you are allowed to do a ecore_timer_del
and also return EINA_FALSE. In that case you have a double eo_del (which is
luckily protected) and a double free (that is not). It does crash on the
double free, but the issue is a lifecycle issue. Will bring a better patch
for this.
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
this means that on loop_get on any obj as long as its a child of a
loop obj... it'll retunr that loop now. it will work. no more code
needed.
we can shortcut this with ui/gfx objects returning the mainloop
singletone.
so i've been doing some debugging and having a mem debugger that
preloads and tracks allocs means you need locks, but locks can do
nasty things after forks + threads.... esp if threads held locks.
this allows mem debugging with preloads easily and doesn't muck things
up.
This fixes a crash in ecore_init, calling a weak function from
libefl that was resolved to NULL.
So, here's a fun thing happening with GCC < 5.3. Since a1a506e13e
all EOAPI and EO class_get() functions are weak symbols. This means
that all APIs inside libefl.so are weak.
As a result, gcc linker with --as-needed skipped linking to libefl
since not a single strong symbol from libefl was required by
libecore. This is actually a bug in gcc linker since we do in fact
use symbols from libefl, just weak ones.
GCC 5.3 seems to be fixed, so people with GCC 5.3+ will not
experience any build/runtime issue. The current patch is
a workaround that bug, by artifically creating a strong symbol
required by ecore.
Other libraries than ecore might also need to call
__efl_internal_init, if they end up not being linked to libefl.
Add ecore_thread_promise_run function that returns a Promise
and runs function in another thread which you can set the
value on a Eina_Promise_Owner.
Eina_Promise* promise;
Ecore_Thread* thread = ecore_thread_promise_run
( &function_heavy, &cancellation_function, private_data,
sizeof(ValueType), &promise);
This calls function_heavy on another thread and returns
the Ecore_Thread and a Eina_Promise as an out-parameter.
Signed-off-by: Cedric Bail <cedric@osg.samsung.com>
this inits a new vpath object and adds it at priority 0 to the vpath
manager so you can use the vpath manager to create vpath file objects
and look things up.
@feature
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.
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.
Summary:
When glib support is enabled (HAVE_GLIB), _ecore_glib_init()
was always reserving resources. However, its counterpart may not
be called when:
- glib is not always integrated and
- when a user didn't explicitly required the integration.
Calling _ecore_glib_init() within the request code will cause the
resources to be reserved only when the integration with glib is
required and furthermore guarantees that resources always have a
chance to be released.
Reviewers: cedric, raster
Subscribers: cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D3749
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
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.
Moved the Ecore.Time @extern struct to Efl lib and defined it as
specified in C specification for struct tm. Thus, bindings can be
automatically generated for where struct tm is used.
Move Ecore_Pos_Map from Ecore_Common.h to ecore_types.eot.
Give it the namespaced Eolian name "Ecore_Pos_Map" to follow the
standards.
Update documentation to refer to Ecore_Pos_Map instead of its previous
enum definition "_Ecore_Pos_Map".
Create the file ecore_types.eot to hold common types related with Ecore.
Add Ecore.Time as an external type to ecore_types.eot.
This type is intended to be a alias to struct tm (from time.h).
That way .eo files have a standard way to reference it.
Each language should manually bind it.
Summary:
- EINA_MAIN_LOOP_CHECK_RETURN should be called before ecore lock
because this may return without ecore_unlock.
- remove EINA_UNLIKELY(!eina_main_loop_is()) which is redundant.
Reviewers: jpeg, jaehwan, cedric, raster
Reviewed By: raster
Subscribers: raster, conr2d, cedric, jpeg
Projects: #efl
Differential Revision: https://phab.enlightenment.org/D3541
Signed-off-by: Cedric BAIL <cedric@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
Summary:
- When Ecore_Task_Cb is not set, _ecore_idle_exiter_constructor
returns without _ecore_unlock(), and remains to be locked.
Reviewers: jpeg
Reviewed By: jpeg
Subscribers: cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D3424
This could lead to some very long and unexpected pause as the timeout passed
to eina_condition_timedwait was passed as a absolute time instead of relative.
Hopefully we don't build rocket.
As reported by vtorri, sometimes ecore_exe on win32 will encounter double
free issues. This was because the variable was freed, but not set to NULL
as expected by the cleanup function.
Fixes T2675
@fix
This fixes the CPU to be usedat 100% for each thread in ecore_exe. This
is obviously not an ideal fix and will be improved in the future.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Output and error threads could not read all the data sent by the child.
Based on a patch by Guillaume Friloux
@fix
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Summary:
When fd handler is deleted by ECORE_CALLBACK_CANCEL, _ecore_main_fdh_poll_del() is not called.
So fd still exists in epoll's event pool.
Reviewers: raster, seoz, woohyun, Hermet, cedric
Reviewed By: cedric
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D3131
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Coverity was complaining about a possible integer overflow. This isn't
actually possible, but coverity has no way to know that because we were
in fact using a too big of a type. I fixed it to be the right type so
now everything should work.
CID 98384
@fix