/* * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre * Copyright (c) Telecom ParisTech 2000-2012 * All rights reserved * * This file is part of GPAC / common tools sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _GF_THREAD_H_ #define _GF_THREAD_H_ #ifdef __cplusplus extern "C" { #endif /*! * \file <gpac/thread.h> * \brief Threading and Mutual Exclusion */ /*! * \addtogroup thr_grp Threading * \ingroup utils_grp * \brief Threading and Mutual Exclusion * *This section documents the threading of the GPAC framework. These provide an easy way to implement *safe multithreaded tools. * @{ */ #include <gpac/tools.h> /*! *\brief Thread states * *Inidcates the execution status of a thread */ enum { /*! the thread has been initialized but is not started yet*/ GF_THREAD_STATUS_STOP = 0, /*! the thread is running*/ GF_THREAD_STATUS_RUN = 1, /*! the thread has exited its body function*/ GF_THREAD_STATUS_DEAD = 2 }; /*! *\brief abstracted thread object * *The abstracted thread object allows you to execute some code independently of the main process of your application. */ typedef struct __tag_thread GF_Thread; /*! *\brief thread constructor * *Constructs a new thread object *\param name log name of the thread if any */ GF_Thread *gf_th_new(const char *name); /*! *\brief thread destructor * * Kills the thread if running and destroys the object *\param th the thread object */ void gf_th_del(GF_Thread *th); /*! * \brief thread run function callback * *The gf_thread_run type is the type for the callback of the \ref gf_thread_run function *\param par opaque user data *\return exit code of the thread, usually 1 for error and 0 if normal execution * */ typedef u32 (*gf_thread_run)(void *par); /*! *\brief thread execution * *Executes the thread with the given function *\param th the thread object *\param run the function this thread will call *\param par the argument to the function the thread will call *\note A thread may be run several times but cannot be run twice in the same time. */ GF_Err gf_th_run(GF_Thread *th, gf_thread_run run, void *par); /*! *\brief thread stopping * *Waits for the thread exit until return *\param th the thread object */ void gf_th_stop(GF_Thread *th); /*! *\brief thread status query * *Gets the thread status *\param th the thread object */ u32 gf_th_status(GF_Thread *th); /*! * thread priorities */ enum { /*!Idle Priority*/ GF_THREAD_PRIORITY_IDLE=0, /*!Less Idle Priority*/ GF_THREAD_PRIORITY_LESS_IDLE, /*!Lowest Priority*/ GF_THREAD_PRIORITY_LOWEST, /*!Low Priority*/ GF_THREAD_PRIORITY_LOW, /*!Normal Priority (the default one)*/ GF_THREAD_PRIORITY_NORMAL, /*!High Priority*/ GF_THREAD_PRIORITY_HIGH, /*!Highest Priority*/ GF_THREAD_PRIORITY_HIGHEST, /*!First real-time priority*/ GF_THREAD_PRIORITY_REALTIME, /*!Last real-time priority*/ GF_THREAD_PRIORITY_REALTIME_END=255 }; /*! *\brief thread priority * *Sets the thread execution priority level. *\param th the thread object *\param priority the desired priority *\note this should be used with caution, especially use of real-time priorities. */ void gf_th_set_priority(GF_Thread *th, s32 priority); /*! *\brief current thread ID * *Gets the ID of the current thread the caller is in. */ u32 gf_th_id(); #ifdef GPAC_ANDROID /*! * Register a function that will be called before pthread_exist is called */ GF_Err gf_register_before_exit_function(GF_Thread *t, u32 (*toRunBeforePthreadExit)(void *param)); /*! Get the current Thread if any. May return NULL */ GF_Thread * gf_th_current(); #endif /* GPAC_ANDROID */ /*! *\brief abstracted mutex object * *The abstracted mutex object allows you to make sure that portions of the code (typically access to variables) cannot be executed *by two threads (or a thread and the main process) at the same time. */ typedef struct __tag_mutex GF_Mutex; /* *\brief mutex constructor * *Contructs a new mutex object *\param log name of the thread if any */ GF_Mutex *gf_mx_new(const char *name); /* *\brief mutex denstructor * *Destroys a mutex object. This will wait for the mutex to be released if needed. *\param mx the mutex object */ void gf_mx_del(GF_Mutex *mx); /* *\brief mutex locking * *Locks the mutex object, making sure that another thread locking this mutex cannot execute until the mutex is unlocked. *\param mx the mutex object *\return 1 if success, 0 if error locking the mutex (which should never happen) */ u32 gf_mx_p(GF_Mutex *mx); /* *\brief mutex unlocking * *Unlocks the mutex object, allowing other threads waiting on this mutex to continue their execution *\param mx the mutex object */ void gf_mx_v(GF_Mutex *mx); /* *\brief mutex non-blocking lock * *Attemps to lock the mutex object without blocking until the object is released. *\param mx the mutex object *\return 1 if the mutex has been successfully locked, in which case it shall then be unlocked, or 0 if the mutex is locked by another thread. */ Bool gf_mx_try_lock(GF_Mutex *mx); /* *\brief get mutex number of locks * *Returns the number of locks on the mutex if the caller thread is holding the mutex. *\param mx the mutex object *\return -1 if the mutex is not hold by the calling thread, or the number of locks (possibly 0) otherwise. */ s32 gf_mx_get_num_locks(GF_Mutex *mx); /********************************************************************* Semaphore Object **********************************************************************/ /*! *\brief abstracted semaphore object * *The abstracted semaphore object allows you to control how portions of the code (typically access to variables) are executed *by two threads (or a thread and the main process) at the same time. The best image for a semaphore is a limited set *of money coins (always easy to understand hmm?). If no money is in the set, nobody can buy anything until a coin is *put back in the set. When the set is full, the money is wasted (call it "the bank"...). */ typedef struct __tag_semaphore GF_Semaphore; /* *\brief semaphore constructor * *Constructs a new semaphore object *\param MaxCount the maximum notification count of this semaphore *\param InitCount the initial notification count of this semaphore upon construction *\return the semaphore object */ GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount); /* *\brief semaphore destructor * *Destructs the semaphore object. This will wait for the semaphore to be released if needed. */ void gf_sema_del(GF_Semaphore *sm); /* *\brief semaphore notification. * *Notifies the semaphore of a certain amount of releases. *\param sm the semaphore object *\param nb_rel sm the number of release to notify *\return GF_TRUE if success, GF_FALSE otherwise */ Bool gf_sema_notify(GF_Semaphore *sm, u32 nb_rel); /* *\brief semaphore wait * *Waits for the semaphore to be accessible (eg, may wait an infinite time). *\param sm the semaphore object */ void gf_sema_wait(GF_Semaphore *sm); /* *\brief semaphore time wait * *Waits for a certain for the semaphore to be accessible, and returns when semaphore is accessible or wait time has passed. *\param sm the semaphore object *\param time_out the amount of time to wait for the release in milliseconds *\return returns 1 if the semaphore was released before the timeout, 0 if the semaphore is still not released after the timeout. */ Bool gf_sema_wait_for(GF_Semaphore *sm, u32 time_out); /*! @} */ #ifdef __cplusplus } #endif #endif /*_GF_THREAD_H_*/