/*
* 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_*/