From: Vincent T. <vt...@un...> - 2009-05-29 19:31:00
|
> @@ -47,7 +47,7 @@ > # define pipe_write(fd, buffer, size) write((fd), buffer, size) > # define pipe_read(fd, buffer, size) read((fd), buffer, size) > # define pipe_close(fd) close(fd) > -# define pipe_fd_invalid -1 > +# define PIPE_FD_INVALID -1 > # define PIPE_FD_ERROR -1 indeed, i forgot that. thanks. Vincent |
From: Mike B. <mi...@ze...> - 2011-06-29 02:41:42
|
On Tue, 28 Jun 2011 19:32:38 -0700 "Enlightenment SVN" <no-...@en...> wrote: > Log: > It doesn't look like this matters, so let's fix the build. > > And if it does matter, I hope it breaks something from cedric. One femur, > for example. Or both. > > Author: sachiel > Date: 2011-06-28 19:32:37 -0700 (Tue, 28 Jun 2011) > New Revision: 60789 > Trac: http://trac.enlightenment.org/e/changeset/60789 > > Modified: > trunk/ecore/src/lib/ecore/ecore_thread.c I'm gonna punch him in his little french ovaries for this one. -- Mike Blumenkrantz Zentific: Coding in binary since '10. |
From: Daniel J. S. <seo...@gm...> - 2011-07-07 00:10:32
|
>> Thanks myself for keeping both of them busy so they don't break SVN *too* much. Impressive commit log :) Daniel Juyung Seo (SeoZ) On Thu, Jul 7, 2011 at 3:08 AM, Enlightenment SVN <no-...@en...> wrote: > Log: > Expand Ecore_Thread docs. > > Thanks cedric for technical advice. > Thanks discomfitor for helping when English vanished. > Thanks myself for keeping both of them busy so they don't break SVN *too* much. > > > Author: sachiel > Date: 2011-07-06 11:08:21 -0700 (Wed, 06 Jul 2011) > New Revision: 61095 > Trac: http://trac.enlightenment.org/e/changeset/61095 > > Modified: > trunk/ecore/src/lib/ecore/Ecore.h trunk/ecore/src/lib/ecore/ecore_thread.c > > Modified: trunk/ecore/src/lib/ecore/Ecore.h > =================================================================== > --- trunk/ecore/src/lib/ecore/Ecore.h 2011-07-06 18:01:42 UTC (rev 61094) > +++ trunk/ecore/src/lib/ecore/Ecore.h 2011-07-06 18:08:21 UTC (rev 61095) > @@ -441,7 +441,7 @@ > typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< Spawned Exe exit event */ > typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; /**< Lines from a child process */ > typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< Data from a child process */ > - typedef struct _Ecore_Thread Ecore_Thread; > + typedef struct _Ecore_Thread Ecore_Thread; /**< A handle for threaded jobs */ > > /** > * @typedef Ecore_Data_Cb Ecore_Data_Cb > @@ -762,46 +762,670 @@ > /** > * @defgroup Ecore_Thread_Group Ecore Thread functions > * > + * Facilities to run heavy tasks in different threads to avoid blocking > + * the main loop. > + * > + * The EFL is, for the most part, not thread safe. This means that if you > + * have some task running in another thread and you have, for example, an > + * Evas object to show the status progress of this task, you cannot update > + * the object from within the thread. This can only be done from the main > + * thread, the one running the main loop. This problem can be solved > + * by running a thread that sends messages to the main one using an > + * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other > + * things like cancelling the thread, your code grows in coplexity and gets > + * much harder to maintain. > + * > + * Ecore Thread is here to solve that problem. It is @b not a simple wrapper > + * around standard POSIX threads (or the equivalent in other systems) and > + * it's not meant to be used to run parallel tasks throughout the entire > + * duration of the program, especially when these tasks are performance > + * critical, as Ecore manages these tasks using a pool of threads based on > + * system configuration. > + * > + * What Ecore Thread does, is make it a lot easier to dispatch a worker > + * function to perform some heavy task and then get the result once it > + * completes, without blocking the application's UI. In addition, cancelling > + * and rescheduling comes practically for free and the developer needs not > + * worry about how many threads are launched, since Ecore will schedule > + * them according to the number of processors the system has and maximum > + * amount of concurrent threads set for the application. > + * > + * At the system level, Ecore will start a new thread on an as-needed basis > + * until the maximum set is reached. When no more threads can be launched, > + * new worker functions will be queued in a waiting list until a thread > + * becomes available. This way, system threads will be shared throughout > + * different worker functions, but running only one at a time. At the same > + * time, a worker function that is rescheduled may be run on a different > + * thread the next time. > + * > + * The ::Ecore_Thread handler has two meanings, depending on what context > + * it is on. The one returned when starting a worker with any of the > + * functions ecore_thread_run() or ecore_thread_feedback_run() is an > + * identifier of that specific instance of the function and can be used from > + * the main loop with the ecore_thread_cancel() and ecore_thread_check() > + * functions. This handler must not be shared with the worker function > + * function running in the thread. This same handler will be the one received > + * on the @c end, @c cancel and @c feedback callbacks. > + * > + * The worker function, that's the one running in the thread, also receives > + * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and > + * ecore_thread_check(), sharing the flag with the main loop. But this > + * handler is also associated with the thread where the function is running. > + * This has strong implications when working with thread local data. > + > + * There are two kinds of worker threads Ecore handles: simple, or short, > + * workers and feedback workers. > + * > + * The first kind is for simple functions that perform a > + * usually small but time consuming task. Ecore will run this function in > + * a thread as soon as one becomes available and notify the calling user of > + * its completion once the task is done. > + * > + * For larger tasks that may require continuous communication with the main > + * program, the feedback workers provide the same functionality plus a way > + * for the function running in the thread to send messages to the main > + * thread. > + * > + * @ingroup Ecore_Group > + * > * @{ > */ > > + /** > + * Schedule a task to run in a parallel thread to avoid locking the main loop > + * > + * @param func_blocking The function that should run in another thread. > + * @param func_end Function to call from main loop when @p func_blocking > + * completes its task successfully (may be NULL) > + * @param func_cancel Function to call from main loop if the thread running > + * @p func_blocking is cancelled or fails to start (may be NULL) > + * @param data User context data to pass to all callbacks. > + * @return A new thread handler, or NULL on failure > + * > + * This function will try to create a new thread to run @p func_blocking in, > + * or if the maximum number of concurrent threads has been reached, will > + * add it to the pending list, where it will wait until a thread becomes > + * available. The return value will be an ::Ecore_Thread handle that can > + * be used to cancel the thread before its completion. > + * > + * @note This function should always return immediately, but in the rare > + * case that Ecore is built with no thread support, @p func_blocking will > + * be called here, actually blocking the main loop. > + * > + * Once a thread becomes available, @p func_blocking will be run in it until > + * it finishes, then @p func_end is called from the thread containing the > + * main loop to inform the user of its completion. While in @p func_blocking, > + * no functions from the EFL can be used, except for those from Eina that are > + * marked to be thread-safe. Even for the latter, caution needs to be taken > + * if the data is shared across several threads. > + * > + * @p func_end will be called from the main thread when @p func_blocking ends, > + * so here it's safe to use anything from the EFL freely. > + * > + * The thread can also be cancelled before its completion calling > + * ecore_thread_cancel(), either from the main thread or @p func_blocking. > + * In this case, @p func_cancel will be called, also from the main thread > + * to inform of this happening. If the thread could not be created, this > + * function will be called and it's @c thread parameter will be NULL. It's > + * also safe to call any EFL function here, as it will be running in the > + * main thread. > + * > + * Inside @p func_blocking, it's possible to call ecore_thread_reschedule() > + * to tell Ecore that this function should be called again. > + * > + * Be aware that no assumptions can be made about the order in which the > + * @p func_end callbacks for each task will be called. Once the function is > + * running in a different thread, it's the OS that will handle its running > + * schedule, and different functions may take longer to finish than others. > + * Also remember that just starting several tasks together doesn't mean they > + * will be running at the same time. Ecore will schedule them based on the > + * number of threads available for the particular system it's running in, > + * so some of the jobs started may be waiting until another one finishes > + * before it can execute its own @p func_blocking. > + * > + * @see ecore_thread_feedback_run() > + * @see ecore_thread_cancel() > + * @see ecore_thread_reschedule() > + * @see ecore_thread_max_set() > + */ > EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking, > Ecore_Thread_Cb func_end, > Ecore_Thread_Cb func_cancel, > const void *data); > + /** > + * Launch a thread to run a task than can talk back to the main thread > + * > + * @param func_heavy The function that should run in another thread. > + * @param func_notify Function that receives the data sent from the thread > + * @param func_end Function to call from main loop when @p func_heavy > + * completes its task successfully > + * @param func_cancel Function to call from main loop if the thread running > + * @p func_heavy is cancelled or fails to start > + * @param data User context data to pass to all callback. > + * @param try_no_queue If you want to run outside of the thread pool. > + * @return A new thread handler, or NULL on failure > + * > + * See ecore_thread_run() for a general description of this function. > + * > + * The difference with the above is that ecore_thread_run() is meant for > + * tasks that don't need to communicate anything until they finish, while > + * this function is provided with a new callback, @p func_notify, that will > + * be called from the main thread for every message sent from @p func_heavy > + * with ecore_thread_feedback(). > + * > + * Like with ecore_thread_run(), a new thread will be launched to run > + * @p func_heavy unless the maximum number of simultaneous threadas has been > + * reached, in which case the function will be scheduled to run whenever a > + * running task ends and a thread becomes free. But if @p try_no_queue is > + * set, Ecore will first try to launch a thread outside of the pool to run > + * the task. If it fails, it will revert to the normal behaviour of using a > + * thread from the pool as if @p try_no_queue had not been set. > + * > + * Keep in mind that Ecore handles the thread pool based on the number of > + * CPUs available, but running a thread outside of the pool doesn't count for > + * this, so having too many of them may have drastic effects over the > + * program's performance. > + * > + * @see ecore_thread_feedback() > + * @see ecore_thread_run() > + * @see ecore_thread_cancel() > + * @see ecore_thread_reschedule() > + * @see ecore_thread_max_set() > + */ > EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, > Ecore_Thread_Notify_Cb func_notify, > Ecore_Thread_Cb func_end, > Ecore_Thread_Cb func_cancel, > const void *data, > Eina_Bool try_no_queue); > + /** > + * Cancel a running thread. > + * > + * @param thread The thread to cancel. > + * @return Will return EINA_TRUE if the thread has been cancelled, > + * EINA_FALSE if it is pending. > + * > + * This function can be called both in the main loop or in the running thread. > + * > + * This function cancels a running thread. If @p thread can be immediately > + * cancelled (it's still pending execution after creation or rescheduling), > + * then the @c cancel callback will be called, @p thread will be freed and > + * the function will return EINA_TRUE. > + * > + * If the thread is already running, then this function returns EINA_FALSE > + * after marking the @p thread as pending cancellation. For the thread to > + * actually be terminated, it needs to return from the user function back > + * into Ecore control. This can happen in several ways: > + * @li The function ends and returns normally. If it hadn't been cancelled, > + * @c func_end would be called here, but instead @c func_cancel will happen. > + * @li The function returns after requesting to be rescheduled with > + * ecore_thread_reschedule(). > + * @li The function is prepared to leave early by checking if > + * ecore_thread_check() returns EINA_TRUE. > + * > + * The user function can cancel itself by calling ecore_thread_cancel(), but > + * it should always use the ::Ecore_Thread handle passed to it and never > + * share it with the main loop thread by means of shared user data or any > + * other way. > + * > + * @p thread will be freed and should not be used again if this function > + * returns EINA_TRUE or after the @c func_cancel callback returns. > + * > + * @see ecore_thread_check() > + */ > EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread); > + /** > + * Checks if a thread is pending cancellation > + * > + * @param thread The thread to test. > + * @return EINA_TRUE if the thread is pending cancellation, > + * EINA_FALSE if it is not. > + * > + * This function can be called both in the main loop or in the running thread. > + * > + * When ecore_thread_cancel() is called on an already running task, the > + * thread is marked as pending cancellation. This function returns EINA_TRUE > + * if this mark is set for the given @p thread and can be used from the > + * main loop thread to check if a still active thread has been cancelled, > + * or from the user function running in the thread to check if it should > + * stop doing what it's doing and return early, effectively cancelling the > + * task. > + * > + * @see ecore_thread_cancel() > + */ > EAPI Eina_Bool ecore_thread_check(Ecore_Thread *thread); > + /** > + * Sends data from the worker thread to the main loop > + * > + * @param thread The current ::Ecore_Thread context to send data from > + * @param msg_data Data to be transmitted to the main loop > + * @return EINA_TRUE if @p msg_data was successfully sent to main loop, > + * EINA_FALSE if anything goes wrong. > + * > + * You should use this function only in the @c func_heavy call. > + * > + * Only the address to @p msg_data will be sent and once this function > + * returns EINA_TRUE, the job running in the thread should never touch the > + * contents of it again. The data sent should be malloc()'ed or something > + * similar, as long as it's not memory local to the thread that risks being > + * overwritten or deleted once it goes out of scope or the thread finishes. > + * > + * Care must be taken that @p msg_data is properly freed in the @c func_notify > + * callback set when creating the thread. > + * > + * @see ecore_thread_feedback_run() > + */ > EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data); > + /** > + * Asks for the function in the thread to be called again at a later time > + * > + * @param thread The current ::Ecore_Thread context to rescheduled > + * @return EINA_TRUE if the task was successfully rescheduled, > + * EINA_FALSE if anything goes wrong. > + * > + * This function should be called only from the same function represented > + * by @pthread. > + * > + * Calling this function will mark the thread for a reschedule, so as soon > + * as it returns, it will be added to the end of the list of pending tasks. > + * If no other tasks are waiting or there are sufficient threads available, > + * the rescheduled task will be launched again immediately. > + * > + * This should never return EINA_FALSE, unless it was called from the wrong > + * thread or with the wrong arguments. > + * > + * The @c func_end callback set when the thread is created will not be > + * called until the function in the thread returns without being rescheduled. > + * Similarly, if the @p thread is cancelled, the reschedule will not take > + * effect. > + */ > EAPI Eina_Bool ecore_thread_reschedule(Ecore_Thread *thread); > + /** > + * Gets the number of active threads running jobs > + * > + * @return Number of active threads running jobs > + * > + * This returns the number of threads currently running jobs of any type > + * through the Ecore_Thread API. > + * > + * @note Jobs started through the ecore_thread_feedback_run() function with > + * the @c try_no_queue parameter set to EINA_TRUE will not be accounted for > + * in the return of this function unless the thread creation fails and it > + * falls back to using one from the pool. > + */ > EAPI int ecore_thread_active_get(void); > + /** > + * Gets the number of short jobs waiting for a thread to run > + * > + * @return Number of pending threads running "short" jobs > + * > + * This returns the number of tasks started with ecore_thread_run() that are > + * pending, waiting for a thread to become available to run them. > + */ > EAPI int ecore_thread_pending_get(void); > + /** > + * Gets the number of feedback jobs waiting for a thread to run > + * > + * @return Number of pending threads running "feedback" jobs > + * > + * This returns the number of tasks started with ecore_thread_feedback_run() > + * that are pending, waiting for a thread to become available to run them. > + */ > EAPI int ecore_thread_pending_feedback_get(void); > + /** > + * Gets the total number of pending jobs > + * > + * @return Number of pending threads running jobs > + * > + * Same as the sum of ecore_thread_pending_get() and > + * ecore_thread_pending_feedback_get(). > + */ > EAPI int ecore_thread_pending_total_get(void); > + /** > + * Gets the maximum number of threads that can run simultaneously > + * > + * @return Max possible number of Ecore_Thread's running concurrently > + * > + * This returns the maximum number of Ecore_Thread's that may be running at > + * the same time. If this number is reached, new jobs started by either > + * ecore_thread_run() or ecore_thread_feedback_run() will be added to the > + * respective pending queue until one of the running threads finishes its > + * task and becomes available to run a new one. > + * > + * By default, this will be the number of available CPUs for the > + * running program (as returned by eina_cpu_count()), or 1 if this value > + * could not be fetched. > + * > + * @see ecore_thread_max_set() > + * @see ecore_thread_max_reset() > + */ > EAPI int ecore_thread_max_get(void); > + /** > + * Sets the maximum number of threads allowed to run simultaneously > + * > + * @param num The new maximum > + * > + * This sets a new value for the maximum number of concurrently running > + * Ecore_Thread's. It @b must an integer between 1 and (2 * @c x), where @c x > + * is the number for CPUs available. > + * > + * @see ecore_thread_max_get() > + * @see ecore_thread_max_reset() > + */ > EAPI void ecore_thread_max_set(int num); > + /** > + * Resets the maximum number of concurrently running threads to the default > + * > + * This resets the value returned by ecore_thread_max_get() back to its > + * default. > + * > + * @see ecore_thread_max_get() > + * @see ecore_thread_max_set() > + */ > EAPI void ecore_thread_max_reset(void); > + /** > + * Gets the number of threads available for running tasks > + * > + * @return The number of available threads > + * > + * Same as doing ecore_thread_max_get() - ecore_thread_active_get(). > + * > + * This function may return a negative number only in the case the user > + * changed the maximum number of running threads while other tasks are > + * running. > + */ > EAPI int ecore_thread_available_get(void); > + /** > + * Adds some data to a hash local to the thread > + * > + * @param thread The thread context the data belongs to > + * @param key The name under which the data will be stored > + * @param value The data to add > + * @param cb Function to free the data when removed from the hash > + * @param direct If true, this will not copy the key string (like > + * eina_hash_direct_add()) > + * @return EINA_TRUE on success, EINA_FALSE on failure > + * > + * Ecore Thread has a mechanism to share data across several worker functions > + * that run on the same system thread. That is, the data is stored per > + * thread and for a worker function to have access to it, it must be run > + * by the same thread that stored the data. > + * > + * When there are no more workers pending, the thread will be destroyed > + * along with the internal hash and any data left in it will be freed with > + * the @p cb function given. > + * > + * This set of functions is useful to share things around several instances > + * of a function when that thing is costly to create and can be reused, but > + * may only be used by one function at a time. > + * > + * For example, if you have a program doing requisitions to a database, > + * these requisitions can be done in threads so that waiting for the > + * database to respond doesn't block the UI. Each of these threads will > + * run a function, and each function will be dependant on a connection to > + * the database, which may not be able to handle more than one request at > + * a time so for each running function you will need one connection handle. > + * The options then are: > + * @li Each function opens a connection when it's called, does the work and > + * closes the connection when it finishes. This may be costly, wasting a lot > + * of time on resolving hostnames, negotiating permissions and allocating > + * memory. > + * @li Open the connections in the main loop and pass it to the threads > + * using the data pointer. Even worse, it's just as costly as before and now > + * it may even be kept with connections open doing nothing until a thread > + * becomes available to run the function. > + * @li Have a way to share connection handles, so that each instance of the > + * function can check if an available connection exists, and if it doesn't, > + * create one and add it to the pool. When no more connections are needed, > + * they are all closed. > + * > + * The last option is the most efficient, but it requires a lot of work to > + * implement properly. Using thread local data helps to achieve the same > + * result while avoiding doing all the tracking work on your code. The way > + * to use it would be, at the worker function, to ask for the connection > + * with ecore_thread_local_data_find() and if it doesn't exist, then open > + * a new one and save it with ecore_thread_local_data_add(). Do the work and > + * forget about the connection handle, when everything is done the function > + * just ends. The next worker to run on that thread will check if a > + * connection exists and find that it does, so the process of opening a > + * new one has been spared. When no more workers exist, the thread is > + * destroyed and the callback used when saving the connection will be called > + * to close it. > + * > + * This function adds the data @p value to the thread data under the given > + * @p key. > + * No other value in the hash may have the same @p key. If you need to > + * change the value under a @p key, or you don't know if one exists already, > + * you can use ecore_thread_local_data_set(). > + * > + * Neither @p key nor @p value may be NULL and @p key will be copied in the > + * hash, unless @p direct is set, in which case the string used should not > + * be freed until the data is removed from the hash. > + * > + * The @p cb function will be called when the data in the hash needs to be > + * freed, be it because it got deleted with ecore_thread_local_data_del() or > + * because @p thread was terminated and the hash destroyed. This parameter > + * may be NULL, in which case @p value needs to be manually freed after > + * removing it from the hash with either ecore_thread_local_data_del() or > + * ecore_thread_local_data_set(), but it's very unlikely that this is what > + * you want. > + * > + * This function, and all of the others in the @c ecore_thread_local_data > + * family of functions, can only be called within the worker function running > + * in the thread. Do not call them from the main loop or from a thread > + * other than the one represented by @p thread. > + * > + * @see ecore_thread_local_data_set() > + * @see ecore_thread_local_data_find() > + * @see ecore_thread_local_data_del() > + */ > EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct); > + /** > + * Sets some data in the hash local to the given thread > + * > + * @param thread The thread context the data belongs to > + * @param key The name under which the data will be stored > + * @param value The data to add > + * @param cb Function to free the data when removed from the hash > + * > + * If no data exists in the hash under the @p key, this function adds > + * @p value in the hash under the given @p key and returns NULL. > + * The key itself is copied. > + * > + * If the hash already contains something under @p key, the data will be > + * replaced by @p value and the old value will be returned. > + * > + * NULL will also be returned if either @p key or @p value are NULL, or if > + * an error occurred. > + * > + * This function, and all of the others in the @c ecore_thread_local_data > + * family of functions, can only be called within the worker function running > + * in the thread. Do not call them from the main loop or from a thread > + * other than the one represented by @p thread. > + * > + * @see ecore_thread_local_data_add() > + * @see ecore_thread_local_data_del() > + * @see ecore_thread_local_data_find() > + */ > EAPI void *ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb); > + /** > + * Gets data stored in the hash local to the given thread > + * > + * @param thread The thread context the data belongs to > + * @param key The name under which the data is stored > + * @return The value under the given key, or NULL on error > + * > + * Finds and return the data stored in the shared hash under the key @p key. > + * > + * This function, and all of the others in the @c ecore_thread_local_data > + * family of functions, can only be called within the worker function running > + * in the thread. Do not call them from the main loop or from a thread > + * other than the one represented by @p thread. > + * > + * @see ecore_thread_local_data_add() > + * @see ecore_thread_local_data_wait() > + */ > EAPI void *ecore_thread_local_data_find(Ecore_Thread *thread, const char *key); > + /** > + * Deletes from the thread's hash the data corresponding to the given key > + * > + * @param thread The thread context the data belongs to > + * @param key The name under which the data is stored > + * @return EINA_TRUE on success, EINA_FALSE on failure > + * > + * If there's any data stored associated with @p key in the global hash, > + * this function will remove it from it and return EINA_TRUE. If no data > + * exists or an error occurs, it returns EINA_FALSE. > + * > + * If the data was added to the hash with a free function, then it will > + * also be freed after removing it from the hash, otherwise it requires > + * to be manually freed by the user, which means that if no other reference > + * to it exists before calling this function, it will result in a memory > + * leak. > + * > + * This function, and all of the others in the @c ecore_thread_local_data > + * family of functions, can only be called within the worker function running > + * in the thread. Do not call them from the main loop or from a thread > + * other than the one represented by @p thread. > + * > + * @see ecore_thread_local_data_add() > + */ > EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread *thread, const char *key); > > + /** > + * Adds some data to a hash shared by all threads > + * > + * @param key The name under which the data will be stored > + * @param value The data to add > + * @param cb Function to free the data when removed from the hash > + * @param direct If true, this will not copy the key string (like > + * eina_hash_direct_add()) > + * @return EINA_TRUE on success, EINA_FALSE on failure > + * > + * Ecore Thread keeps a hash that can be used to share data across several > + * threads, including the main loop one, without having to manually handle > + * mutexes to do so safely. > + * > + * This function adds the data @p value to this hash under the given @p key. > + * No other value in the hash may have the same @p key. If you need to > + * change the value under a @p key, or you don't know if one exists already, > + * you can use ecore_thread_global_data_set(). > + * > + * Neither @p key nor @p value may be NULL and @p key will be copied in the > + * hash, unless @p direct is set, in which case the string used should not > + * be freed until the data is removed from the hash. > + * > + * The @p cb function will be called when the data in the hash needs to be > + * freed, be it because it got deleted with ecore_thread_global_data_del() or > + * because Ecore Thread was shut down and the hash destroyed. This parameter > + * may be NULL, in which case @p value needs to be manually freed after > + * removing it from the hash with either ecore_thread_global_data_del() or > + * ecore_thread_global_data_set(). > + * > + * Manually freeing any data that was added to the hash with a @p cb function > + * is likely to produce a segmentation fault, or any other strange > + * happenings, later on in the program. > + * > + * @see ecore_thread_global_data_del() > + * @see ecore_thread_global_data_set() > + * @see ecore_thread_global_data_find() > + */ > EAPI Eina_Bool ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct); > + /** > + * Sets some data in the hash shared by all threads > + * > + * @param key The name under which the data will be stored > + * @param value The data to add > + * @param cb Function to free the data when removed from the hash > + * > + * If no data exists in the hash under the @p key, this function adds > + * @p value in the hash under the given @p key and returns NULL. > + * The key itself is copied. > + * > + * If the hash already contains something under @p key, the data will be > + * replaced by @p value and the old value will be returned. > + * > + * NULL will also be returned if either @p key or @p value are NULL, or if > + * an error occurred. > + * > + * @see ecore_thread_global_data_add() > + * @see ecore_thread_global_data_del() > + * @see ecore_thread_global_data_find() > + */ > EAPI void *ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb); > + /** > + * Gets data stored in the hash shared by all threads > + * > + * @param key The name under which the data is stored > + * @return The value under the given key, or NULL on error > + * > + * Finds and return the data stored in the shared hash under the key @p key. > + * > + * Keep in mind that the data returned may be used by more than one thread > + * at the same time and no reference counting is done on it by Ecore. > + * Freeing the data or modifying its contents may require additional > + * precautions to be considered, depending on the application's design. > + * > + * @see ecore_thread_global_data_add() > + * @see ecore_thread_global_data_wait() > + */ > EAPI void *ecore_thread_global_data_find(const char *key); > + /** > + * Deletes from the shared hash the data corresponding to the given key > + * > + * @param key The name under which the data is stored > + * @return EINA_TRUE on success, EINA_FALSE on failure > + * > + * If there's any data stored associated with @p key in the global hash, > + * this function will remove it from it and return EINA_TRUE. If no data > + * exists or an error occurs, it returns EINA_FALSE. > + * > + * If the data was added to the hash with a free function, then it will > + * also be freed after removing it from the hash, otherwise it requires > + * to be manually freed by the user, which means that if no other reference > + * to it exists before calling this function, it will result in a memory > + * leak. > + * > + * Note, also, that freeing data that other threads may be using will result > + * in a crash, so appropriate care must be taken by the application when > + * that possibility exists. > + * > + * @see ecore_thread_global_data_add() > + */ > EAPI Eina_Bool ecore_thread_global_data_del(const char *key); > - EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); > - > /** > - * @} > + * Gets data stored in the shared hash, or wait for it if it doesn't exist > + * > + * @param key The name under which the data is stored > + * @param seconds The amount of time in seconds to wait for the data. > + * @return The value under the given key, or NULL on error > + * > + * Finds and return the data stored in the shared hash under the key @p key. > + * > + * If there's nothing in the hash under the given @p key, the function > + * will block and wait up to @p seconds seconds for some other thread to > + * add it with either ecore_thread_global_data_add() or > + * ecore_thread_global_data_set(). If after waiting there's still no data > + * to get, NULL will be returned. > + * > + * If @p seconds is 0, then no waiting will happen and this function works > + * like ecore_thread_global_data_find(). If @p seconds is less than 0, then > + * the function will wait indefinitely. > + * > + * Keep in mind that the data returned may be used by more than one thread > + * at the same time and no reference counting is done on it by Ecore. > + * Freeing the data or modifying its contents may require additional > + * precautions to be considered, depending on the application's design. > + * > + * @see ecore_thread_global_data_add() > + * @see ecore_thread_global_data_find() > */ > + EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); > > + /** > + * @} > + */ > + > /** > * @defgroup Ecore_Time_Group Ecore Time functions > * > > Modified: trunk/ecore/src/lib/ecore/ecore_thread.c > =================================================================== > --- trunk/ecore/src/lib/ecore/ecore_thread.c 2011-07-06 18:01:42 UTC (rev 61094) > +++ trunk/ecore/src/lib/ecore/ecore_thread.c 2011-07-06 18:08:21 UTC (rev 61095) > @@ -861,40 +861,6 @@ > } > } > > -/** > - * @addtogroup Ecore_Group Ecore - Main Loop and Job Functions. > - * > - * @{ > - */ > - > -/** > - * @addtogroup Ecore_Thread_Group Ecore Thread functions > - * > - * These functions allow for ecore-managed threads which integrate with ecore's main loop. > - * > - * @{ > - */ > - > -/** > - * @brief Run some blocking code in a parallel thread to avoid locking the main loop. > - * @param func_blocking The function that should run in another thread. > - * @param func_end The function that will be called in the main loop if the thread terminate correctly. > - * @param func_cancel The function that will be called in the main loop if the thread is cancelled. > - * @param data User context data to pass to all callback. > - * @return A reference to the newly created thread instance, or NULL if it failed. > - * > - * ecore_thread_run provide a facility for easily managing blocking task in a > - * parallel thread. You should provide three function. The first one, func_blocking, > - * that will do the blocking work in another thread (so you should not use the > - * EFL in it except Eina if you are careful). The second one, func_end, > - * that will be called in Ecore main loop when func_blocking is done. So you > - * can use all the EFL inside this function. The last one, func_cancel, will > - * be called in the main loop if the thread is cancelled or could not run at all. > - * > - * Be aware, that you can't make assumption on the result order of func_end > - * after many call to ecore_thread_run, as we start as much thread as the > - * host CPU can handle. > - */ > EAPI Ecore_Thread * > ecore_thread_run(Ecore_Thread_Cb func_blocking, > Ecore_Thread_Cb func_end, > @@ -1003,23 +969,6 @@ > #endif > } > > -/** > - * @brief Cancel a running thread. > - * @param thread The thread to cancel. > - * @return Will return EINA_TRUE if the thread has been cancelled, > - * EINA_FALSE if it is pending. > - * > - * ecore_thread_cancel give the possibility to cancel a task still running. It > - * will return EINA_FALSE, if the destruction is delayed or EINA_TRUE if it is > - * cancelled after this call. > - * > - * This function work in the main loop and in the thread, but you should not pass > - * the Ecore_Thread variable from main loop to the worker thread in any structure. > - * You should always use the one passed to the Ecore_Thread_Heavy_Cb. > - * > - * func_end, func_cancel will destroy the handler, so don't use it after. > - * And if ecore_thread_cancel return EINA_TRUE, you should not use Ecore_Thread also. > - */ > EAPI Eina_Bool > ecore_thread_cancel(Ecore_Thread *thread) > { > @@ -1090,14 +1039,6 @@ > #endif > } > > -/** > - * @brief Tell if a thread was canceled or not. > - * @param thread The thread to test. > - * @return EINA_TRUE if the thread is cancelled, > - * EINA_FALSE if it is not. > - * > - * You can use this function in main loop and in the thread. > - */ > EAPI Eina_Bool > ecore_thread_check(Ecore_Thread *thread) > { > @@ -1107,34 +1048,6 @@ > return worker->cancel; > } > > -/** > - * @brief Run some heavy code in a parallel thread to avoid locking the main loop. > - * @param func_heavy The function that should run in another thread. > - * @param func_notify The function that will receive the data send by func_heavy in the main loop. > - * @param func_end The function that will be called in the main loop if the thread terminate correctly. > - * @param func_cancel The function that will be called in the main loop if the thread is cancelled. > - * @param data User context data to pass to all callback. > - * @param try_no_queue If you want to run outside of the thread pool. > - * @return A reference to the newly created thread instance, or NULL if it failed. > - * > - * ecore_thread_feedback_run provide a facility for easily managing heavy task in a > - * parallel thread. You should provide four functions. The first one, func_heavy, > - * that will do the heavy work in another thread (so you should not use the > - * EFL in it except Eina and Eet if you are careful). The second one, func_notify, > - * will receive the data send from the thread function (func_heavy) by ecore_thread_feedback > - * in the main loop (and so, can use all the EFL). The third, func_end, > - * that will be called in Ecore main loop when func_heavy is done. So you > - * can use all the EFL inside this function. The last one, func_cancel, will > - * be called in the main loop also, if the thread is cancelled or could not run at all. > - * > - * Be aware, that you can't make assumption on the result order of func_end > - * after many call to ecore_feedback_run, as we start as much thread as the > - * host CPU can handle. > - * > - * If you set try_no_queue, it will try to run outside of the thread pool, this can bring > - * the CPU down, so be careful with that. Of course if it can't start a new thread, it will > - * try to use one from the pool. > - */ > EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, > Ecore_Thread_Notify_Cb func_notify, > Ecore_Thread_Cb func_end, > @@ -1279,18 +1192,6 @@ > #endif > } > > -/** > - * @brief Send data to main loop from worker thread. > - * @param thread The current Ecore_Thread context to send data from > - * @param data Data to be transmitted to the main loop > - * @return EINA_TRUE if data was successfully send to main loop, > - * EINA_FALSE if anything goes wrong. > - * > - * After a succesfull call, the data should be considered owned > - * by the main loop. > - * > - * You should use this function only in the func_heavy call. > - */ > EAPI Eina_Bool > ecore_thread_feedback(Ecore_Thread *thread, const void *data) > { > @@ -1313,17 +1214,6 @@ > #endif > } > > -/** > - * @brief Plan to recall the heavy function once it exist it. > - * @param thread The current Ecore_Thread context to reschedule > - * @return EINA_TRUE if data was successfully send to main loop, > - * EINA_FALSE if anything goes wrong. > - * > - * After a succesfull call, you can still do what you want in your thread, it > - * will only reschedule it once you exit the heavy loop. > - * > - * You should use this function only in the func_heavy call. > - */ > EAPI Eina_Bool > ecore_thread_reschedule(Ecore_Thread *thread) > { > @@ -1339,12 +1229,6 @@ > return EINA_TRUE; > } > > -/** > - * @brief Get number of active thread jobs > - * @return Number of active threads running jobs > - * This returns the number of threads currently running jobs through the > - * ecore_thread api. > - */ > EAPI int > ecore_thread_active_get(void) > { > @@ -1355,12 +1239,6 @@ > #endif > } > > -/** > - * @brief Get number of pending (short) thread jobs > - * @return Number of pending threads running "short" jobs > - * This returns the number of threads currently running jobs through the > - * ecore_thread_run api call. > - */ > EAPI int > ecore_thread_pending_get(void) > { > @@ -1375,12 +1253,6 @@ > #endif > } > > -/** > - * @brief Get number of pending feedback thread jobs > - * @return Number of pending threads running "feedback" jobs > - * This returns the number of threads currently running jobs through the > - * ecore_thread_feedback_run api call. > - */ > EAPI int > ecore_thread_pending_feedback_get(void) > { > @@ -1395,12 +1267,6 @@ > #endif > } > > -/** > - * @brief Get number of pending thread jobs > - * @return Number of pending threads running jobs > - * This returns the number of threads currently running jobs through the > - * ecore_thread_run and ecore_thread_feedback_run api calls combined. > - */ > EAPI int > ecore_thread_pending_total_get(void) > { > @@ -1415,24 +1281,12 @@ > #endif > } > > -/** > - * @brief Get the max number of threads that can run simultaneously > - * @return Max number of threads ecore will run > - * This returns the total number of threads that ecore will attempt to run > - * simultaneously. > - */ > EAPI int > ecore_thread_max_get(void) > { > return _ecore_thread_count_max; > } > > -/** > - * @brief Set the max number of threads that can run simultaneously > - * @param num The new maximum > - * This sets the maximum number of threads that ecore will try to run > - * simultaneously. This number cannot be < 1 or >= 2x the number of active cpus. > - */ > EAPI void > ecore_thread_max_set(int num) > { > @@ -1443,24 +1297,12 @@ > _ecore_thread_count_max = num; > } > > -/** > - * @brief Reset the max number of threads that can run simultaneously > - * This resets the maximum number of threads that ecore will try to run > - * simultaneously to the number of active cpus. > - */ > EAPI void > ecore_thread_max_reset(void) > { > _ecore_thread_count_max = eina_cpu_count(); > } > > -/** > - * @brief Get the number of threads which are available to be used > - * @return The number of available threads > - * This returns the number of threads slots that ecore has currently available. > - * Assuming that you haven't changed the max number of threads with @ref ecore_thread_max_set > - * this should be equal to (num_cpus - (active_running + active_feedback_running)) > - */ > EAPI int > ecore_thread_available_get(void) > { > @@ -1475,21 +1317,6 @@ > #endif > } > > -/** > - * @brief Add data to the thread for subsequent use > - * @param thread The thread context to add to > - * @param key The name string to add the data with > - * @param value The data to add > - * @param cb The callback to free the data with > - * @param direct If true, this will not copy the key string (like eina_hash_direct_add) > - * @return EINA_TRUE on success, EINA_FALSE on failure > - * This adds data to the thread context, allowing the thread > - * to retrieve and use it without complicated mutexing. This function can only be called by a > - * *_run thread INSIDE the thread and will return EINA_FALSE in any case but success. > - * All data added to the thread will be freed with its associated callback (if present) > - * upon thread termination. If no callback is specified, it is expected that the user will free the > - * data, but this is most likely not what you want. > - */ > EAPI Eina_Bool > ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct) > { > @@ -1525,19 +1352,6 @@ > #endif > } > > -/** > - * @brief Modify data in the thread, or add if not found > - * @param thread The thread context > - * @param key The name string to add the data with > - * @param value The data to add > - * @param cb The callback to free the data with > - * @return The old data associated with @p key on success if modified, NULL if added > - * This adds/modifies data in the thread context, adding only if modify fails. > - * This function can only be called by a *_run thread INSIDE the thread. > - * All data added to the thread pool will be freed with its associated callback (if present) > - * upon thread termination. If no callback is specified, it is expected that the user will free the > - * data, but this is most likely not what you want. > - */ > EAPI void * > ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb) > { > @@ -1571,15 +1385,6 @@ > #endif > } > > -/** > - * @brief Find data in the thread's data > - * @param thread The thread context > - * @param key The name string the data is associated with > - * @return The value, or NULL on error > - * This finds data in the thread context that has been previously added with @ref ecore_thread_local_data_add > - * This function can only be called by a *_run thread INSIDE the thread, and will return NULL > - * in any case but success. > - */ > > EAPI void * > ecore_thread_local_data_find(Ecore_Thread *thread, const char *key) > @@ -1602,15 +1407,6 @@ > #endif > } > > -/** > - * @brief Delete data from the thread's data > - * @param thread The thread context > - * @param key The name string the data is associated with > - * @return EINA_TRUE on success, EINA_FALSE on failure > - * This deletes the data pointer from the thread context which was previously added with @ref ecore_thread_local_data_add > - * This function can only be called by a *_run thread INSIDE the thread, and will return EINA_FALSE > - * in any case but success. Note that this WILL free the data if a callback was specified. > - */ > EAPI Eina_Bool > ecore_thread_local_data_del(Ecore_Thread *thread, const char *key) > { > @@ -1631,18 +1427,6 @@ > #endif > } > > -/** > - * @brief Add data to the global data > - * @param key The name string to add the data with > - * @param value The data to add > - * @param cb The optional callback to free the data with once ecore is shut down > - * @param direct If true, this will not copy the key string (like eina_hash_direct_add) > - * @return EINA_TRUE on success, EINA_FALSE on failure > - * This adds data to the global thread data, and will return EINA_FALSE in any case but success. > - * All data added to global can be manually freed, or a callback can be provided with @p cb which will > - * be called upon ecore_thread shutting down. Note that if you have manually freed data that a callback > - * was specified for, you will most likely encounter a segv later on. > - */ > EAPI Eina_Bool > ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct) > { > @@ -1678,19 +1462,6 @@ > #endif > } > > -/** > - * @brief Add data to the global data > - * @param key The name string to add the data with > - * @param value The data to add > - * @param cb The optional callback to free the data with once ecore is shut down > - * @return An Ecore_Thread_Data on success, NULL on failure > - * This adds data to the global thread data and returns NULL, or replaces the previous data > - * associated with @p key and returning the previous data if it existed. To see if an error occurred, > - * one must use eina_error_get. > - * All data added to global can be manually freed, or a callback can be provided with @p cb which will > - * be called upon ecore_thread shutting down. Note that if you have manually freed data that a callback > - * was specified for, you will most likely encounter a segv later on. > - */ > EAPI void * > ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb) > { > @@ -1727,18 +1498,6 @@ > #endif > } > > -/** > - * @brief Find data in the global data > - * @param key The name string the data is associated with > - * @return The value, or NULL on error > - * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add > - * This function will return NULL in any case but success. > - * All data added to global can be manually freed, or a callback can be provided with @p cb which will > - * be called upon ecore_thread shutting down. Note that if you have manually freed data that a callback > - * was specified for, you will most likely encounter a segv later on. > - * @note Keep in mind that the data returned can be used by multiple threads at a time, so you will most likely want to mutex > - * if you will be doing anything with it. > - */ > > EAPI void * > ecore_thread_global_data_find(const char *key) > @@ -1758,14 +1517,6 @@ > #endif > } > > -/** > - * @brief Delete data from the global data > - * @param key The name string the data is associated with > - * @return EINA_TRUE on success, EINA_FALSE on failure > - * This deletes the data pointer from the global data which was previously added with @ref ecore_thread_global_data_add > - * This function will return EINA_FALSE in any case but success. > - * Note that this WILL free the data if an @c Eina_Free_Cb was specified when the data was added. > - */ > EAPI Eina_Bool > ecore_thread_global_data_del(const char *key) > { > @@ -1789,18 +1540,6 @@ > #endif > } > > -/** > - * @brief Find data in the global data and optionally wait for the data if not found > - * @param key The name string the data is associated with > - * @param seconds The amount of time in seconds to wait for the data. If 0, the call will be async and not wait for data. > - * If < 0 the call will wait indefinitely for the data. > - * @return The value, or NULL on failure > - * This finds data in the global data that has been previously added with @ref ecore_thread_global_data_add > - * This function will return NULL in any case but success. > - * Use @p seconds to specify the amount of time to wait. Use > 0 for an actual wait time, 0 to not wait, and < 0 to wait indefinitely. > - * @note Keep in mind that the data returned can be used by multiple threads at a time, so you will most likely want to mutex > - * if you will be doing anything with it. > - */ > EAPI void * > ecore_thread_global_data_wait(const char *key, double seconds) > { > @@ -1843,11 +1582,3 @@ > return NULL; > #endif > } > - > -/** > - * @} > - */ > - > -/** > - * @} > - */ > > > ------------------------------------------------------------------------------ > All of the data generated in your IT infrastructure is seriously valuable. > Why? It contains a definitive record of application performance, security > threats, fraudulent activity, and more. Splunk takes this data and makes > sense of it. IT sense. And common sense. > http://p.sf.net/sfu/splunk-d2d-c2 > _______________________________________________ > enlightenment-svn mailing list > enl...@li... > https://lists.sourceforge.net/lists/listinfo/enlightenment-svn > |
From: David S. <on...@gm...> - 2011-10-28 05:30:35
Attachments:
signature.asc
|
On Thu, 27 Oct 2011 06:19:12 -0700 "Enlightenment SVN" <no-...@en...> wrote: > + * DO NOT use this function unless you are the person God comes to > ask for > + * advice when He has trouble managing the Universe. Ah, so I CAN still use it then. :-P -- A big old stinking pile of genius that no one wants coz there are too many silver coated monkeys in the world. |
From: Mike B. <mi...@ze...> - 2011-10-28 05:50:04
|
On Fri, 28 Oct 2011 15:29:06 +1000 David Seikel <on...@gm...> wrote: > On Thu, 27 Oct 2011 06:19:12 -0700 "Enlightenment SVN" > <no-...@en...> wrote: > > > + * DO NOT use this function unless you are the person God comes to > > ask for > > + * advice when He has trouble managing the Universe. > > Ah, so I CAN still use it then. :-P > I wasn't asking for advice, I was complaining while drinking. There's a difference. -- Mike Blumenkrantz Zentific: Doctor recommended, mother approved. |