1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #ifndef __PJ_OS_H__
21 #define __PJ_OS_H__
22 
23 /**
24  * @file os.h
25  * @brief OS dependent functions
26  */
27 #include <pj/types.h>
28 
29 PJ_BEGIN_DECL
30 
31 /**
32  * @defgroup PJ_OS Operating System Dependent Functionality.
33  */
34 
35 
36 /* **************************************************************************/
37 /**
38  * @defgroup PJ_SYS_INFO System Information
39  * @ingroup PJ_OS
40  * @{
41  */
42 
43 /**
44  * These enumeration contains constants to indicate support of miscellaneous
45  * system features. These will go in "flags" field of #pj_sys_info structure.
46  */
47 typedef enum pj_sys_info_flag
48 {
49     /**
50      * Support for Apple iOS background feature.
51      */
52     PJ_SYS_HAS_IOS_BG = 1
53 
54 } pj_sys_info_flag;
55 
56 
57 /**
58  * This structure contains information about the system. Use #pj_get_sys_info()
59  * to obtain the system information.
60  */
61 typedef struct pj_sys_info
62 {
63     /**
64      * Null terminated string containing processor information (e.g. "i386",
65      * "x86_64"). It may contain empty string if the value cannot be obtained.
66      */
67     pj_str_t	machine;
68 
69     /**
70      * Null terminated string identifying the system operation (e.g. "Linux",
71      * "win32", "wince"). It may contain empty string if the value cannot be
72      * obtained.
73      */
74     pj_str_t	os_name;
75 
76     /**
77      * A number containing the operating system version number. By convention,
78      * this field is divided into four bytes, where the highest order byte
79      * contains the most major version of the OS, the next less significant
80      * byte contains the less major version, and so on. How the OS version
81      * number is mapped into these four bytes would be specific for each OS.
82      * For example, Linux-2.6.32-28 would yield "os_ver" value of 0x0206201c,
83      * while for Windows 7 it will be 0x06010000 (because dwMajorVersion is
84      * 6 and dwMinorVersion is 1 for Windows 7).
85      *
86      * This field may contain zero if the OS version cannot be obtained.
87      */
88     pj_uint32_t	os_ver;
89 
90     /**
91      * Null terminated string identifying the SDK name that is used to build
92      * the library (e.g. "glibc", "uclibc", "msvc", "wince"). It may contain
93      * empty string if the value cannot eb obtained.
94      */
95     pj_str_t	sdk_name;
96 
97     /**
98      * A number containing the SDK version, using the numbering convention as
99      * the "os_ver" field. The value will be zero if the version cannot be
100      * obtained.
101      */
102     pj_uint32_t	sdk_ver;
103 
104     /**
105      * A longer null terminated string identifying the underlying system with
106      * as much information as possible.
107      */
108     pj_str_t	info;
109 
110     /**
111      * Other flags containing system specific information. The value is
112      * bitmask of #pj_sys_info_flag constants.
113      */
114     pj_uint32_t	flags;
115 
116 } pj_sys_info;
117 
118 
119 /**
120  * Obtain the system information.
121  *
122  * @return	System information structure.
123  */
124 PJ_DECL(const pj_sys_info*) pj_get_sys_info(void);
125 
126 /*
127  * @}
128  */
129 
130 /* **************************************************************************/
131 /**
132  * @defgroup PJ_THREAD Threads
133  * @ingroup PJ_OS
134  * @{
135  * This module provides multithreading API.
136  *
137  * \section pj_thread_examples_sec Examples
138  *
139  * For examples, please see:
140  *  - \ref page_pjlib_thread_test
141  *  - \ref page_pjlib_sleep_test
142  *
143  */
144 
145 /**
146  * Thread creation flags:
147  * - PJ_THREAD_SUSPENDED: specify that the thread should be created suspended.
148  */
149 typedef enum pj_thread_create_flags
150 {
151     PJ_THREAD_SUSPENDED = 1
152 } pj_thread_create_flags;
153 
154 
155 /**
156  * Type of thread entry function.
157  */
158 typedef int (PJ_THREAD_FUNC pj_thread_proc)(void*);
159 
160 /**
161  * Size of thread struct.
162  */
163 #if !defined(PJ_THREAD_DESC_SIZE)
164 #   define PJ_THREAD_DESC_SIZE	    (64)
165 #endif
166 
167 /**
168  * Thread structure, to thread's state when the thread is created by external
169  * or native API.
170  */
171 typedef long pj_thread_desc[PJ_THREAD_DESC_SIZE];
172 
173 /**
174  * Get process ID.
175  * @return process ID.
176  */
177 PJ_DECL(pj_uint32_t) pj_getpid(void);
178 
179 /**
180  * Create a new thread.
181  *
182  * @param pool          The memory pool from which the thread record
183  *                      will be allocated from.
184  * @param thread_name   The optional name to be assigned to the thread.
185  * @param proc          Thread entry function.
186  * @param arg           Argument to be passed to the thread entry function.
187  * @param stack_size    The size of the stack for the new thread, or ZERO or
188  *                      PJ_THREAD_DEFAULT_STACK_SIZE to let the
189  *		        library choose the reasonable size for the stack.
190  *                      For some systems, the stack will be allocated from
191  *                      the pool, so the pool must have suitable capacity.
192  * @param flags         Flags for thread creation, which is bitmask combination
193  *                      from enum pj_thread_create_flags.
194  * @param thread        Pointer to hold the newly created thread.
195  *
196  * @return	        PJ_SUCCESS on success, or the error code.
197  */
198 PJ_DECL(pj_status_t) pj_thread_create(  pj_pool_t *pool,
199                                         const char *thread_name,
200 				        pj_thread_proc *proc,
201                                         void *arg,
202 				        pj_size_t stack_size,
203                                         unsigned flags,
204 					pj_thread_t **thread );
205 
206 /**
207  * Register a thread that was created by external or native API to PJLIB.
208  * This function must be called in the context of the thread being registered.
209  * When the thread is created by external function or API call,
210  * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
211  * cooperate with PJLIB's framework. During registration, some data needs to
212  * be maintained, and this data must remain available during the thread's
213  * lifetime.
214  *
215  * @param thread_name   The optional name to be assigned to the thread.
216  * @param desc          Thread descriptor, which must be available throughout
217  *                      the lifetime of the thread.
218  * @param thread        Pointer to hold the created thread handle.
219  *
220  * @return              PJ_SUCCESS on success, or the error code.
221  */
222 PJ_DECL(pj_status_t) pj_thread_register ( const char *thread_name,
223 					  pj_thread_desc desc,
224 					  pj_thread_t **thread);
225 
226 /**
227  * Check if this thread has been registered to PJLIB.
228  *
229  * @return		Non-zero if it is registered.
230  */
231 PJ_DECL(pj_bool_t) pj_thread_is_registered(void);
232 
233 
234 /**
235  * Get thread priority value for the thread.
236  *
237  * @param thread	Thread handle.
238  *
239  * @return		Thread priority value, or -1 on error.
240  */
241 PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
242 
243 
244 /**
245  * Set the thread priority. The priority value must be in the priority
246  * value range, which can be retrieved with #pj_thread_get_prio_min() and
247  * #pj_thread_get_prio_max() functions.
248  *
249  * @param thread	Thread handle.
250  * @param prio		New priority to be set to the thread.
251  *
252  * @return		PJ_SUCCESS on success or the error code.
253  */
254 PJ_DECL(pj_status_t) pj_thread_set_prio(pj_thread_t *thread,  int prio);
255 
256 /**
257  * Get the lowest priority value available for this thread.
258  *
259  * @param thread	Thread handle.
260  * @return		Minimum thread priority value, or -1 on error.
261  */
262 PJ_DECL(int) pj_thread_get_prio_min(pj_thread_t *thread);
263 
264 
265 /**
266  * Get the highest priority value available for this thread.
267  *
268  * @param thread	Thread handle.
269  * @return		Minimum thread priority value, or -1 on error.
270  */
271 PJ_DECL(int) pj_thread_get_prio_max(pj_thread_t *thread);
272 
273 
274 /**
275  * Return native handle from pj_thread_t for manipulation using native
276  * OS APIs.
277  *
278  * @param thread	PJLIB thread descriptor.
279  *
280  * @return		Native thread handle. For example, when the
281  *			backend thread uses pthread, this function will
282  *			return pointer to pthread_t, and on Windows,
283  *			this function will return HANDLE.
284  */
285 PJ_DECL(void*) pj_thread_get_os_handle(pj_thread_t *thread);
286 
287 /**
288  * Get thread name.
289  *
290  * @param thread    The thread handle.
291  *
292  * @return Thread name as null terminated string.
293  */
294 PJ_DECL(const char*) pj_thread_get_name(pj_thread_t *thread);
295 
296 /**
297  * Resume a suspended thread.
298  *
299  * @param thread    The thread handle.
300  *
301  * @return zero on success.
302  */
303 PJ_DECL(pj_status_t) pj_thread_resume(pj_thread_t *thread);
304 
305 /**
306  * Get the current thread.
307  *
308  * @return Thread handle of current thread.
309  */
310 PJ_DECL(pj_thread_t*) pj_thread_this(void);
311 
312 /**
313  * Join thread, and block the caller thread until the specified thread exits.
314  * If it is called from within the thread itself, it will return immediately
315  * with failure status.
316  * If the specified thread has already been dead, or it does not exist,
317  * the function will return immediately with successful status.
318  *
319  * @param thread    The thread handle.
320  *
321  * @return PJ_SUCCESS on success.
322  */
323 PJ_DECL(pj_status_t) pj_thread_join(pj_thread_t *thread);
324 
325 
326 /**
327  * Destroy thread and release resources allocated for the thread.
328  * However, the memory allocated for the pj_thread_t itself will only be released
329  * when the pool used to create the thread is destroyed.
330  *
331  * @param thread    The thread handle.
332  *
333  * @return zero on success.
334  */
335 PJ_DECL(pj_status_t) pj_thread_destroy(pj_thread_t *thread);
336 
337 
338 /**
339  * Put the current thread to sleep for the specified miliseconds.
340  *
341  * @param msec Miliseconds delay.
342  *
343  * @return zero if successfull.
344  */
345 PJ_DECL(pj_status_t) pj_thread_sleep(unsigned msec);
346 
347 /**
348  * @def PJ_CHECK_STACK()
349  * PJ_CHECK_STACK() macro is used to check the sanity of the stack.
350  * The OS implementation may check that no stack overflow occurs, and
351  * it also may collect statistic about stack usage.
352  */
353 #if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
354 
355 #  define PJ_CHECK_STACK() pj_thread_check_stack(__FILE__, __LINE__)
356 
357 /** @internal
358  * The implementation of stack checking.
359  */
360 PJ_DECL(void) pj_thread_check_stack(const char *file, int line);
361 
362 /** @internal
363  * Get maximum stack usage statistic.
364  */
365 PJ_DECL(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread);
366 
367 /** @internal
368  * Dump thread stack status.
369  */
370 PJ_DECL(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
371 					      const char **file,
372 					      int *line);
373 #else
374 
375 #  define PJ_CHECK_STACK()
376 /** pj_thread_get_stack_max_usage() for the thread */
377 #  define pj_thread_get_stack_max_usage(thread)	    0
378 /** pj_thread_get_stack_info() for the thread */
379 #  define pj_thread_get_stack_info(thread,f,l)	    (*(f)="",*(l)=0)
380 #endif	/* PJ_OS_HAS_CHECK_STACK */
381 
382 /**
383  * @}
384  */
385 
386 /* **************************************************************************/
387 /**
388  * @defgroup PJ_SYMBIAN_OS Symbian OS Specific
389  * @ingroup PJ_OS
390  * @{
391  * Functionalities specific to Symbian OS.
392  *
393  * Symbian OS strongly discourages the use of polling since this wastes
394  * CPU power, and instead provides Active Object and Active Scheduler
395  * pattern to allow application (in this case, PJLIB) to register asynchronous
396  * tasks. PJLIB port for Symbian complies to this recommended behavior.
397  * As the result, few things have been changed in PJLIB for Symbian:
398  *	- the timer heap (see @ref PJ_TIMER) is implemented with active
399  *	  object framework, and each timer entry registered to the timer
400  *	  heap will register an Active Object to the Active Scheduler.
401  *	  Because of this, polling the timer heap with pj_timer_heap_poll()
402  *	  is no longer necessary, and this function will just evaluate
403  *	  to nothing.
404  *	- the ioqueue (see @ref PJ_IOQUEUE) is also implemented with
405  *	  active object framework, with each asynchronous operation will
406  *	  register an Active Object to the Active Scheduler. Because of
407  *	  this, polling the ioqueue with pj_ioqueue_poll() is no longer
408  *	  necessary, and this function will just evaluate to nothing.
409  *
410  * Since timer heap and ioqueue polling are no longer necessary, Symbian
411  * application can now poll for all events by calling
412  * \a User::WaitForAnyRequest() and \a CActiveScheduler::RunIfReady().
413  * PJLIB provides a thin wrapper which calls these two functions,
414  * called pj_symbianos_poll().
415  */
416 
417 /**
418  * Wait the completion of any Symbian active objects. When the timeout
419  * value is not specified (the \a ms_timeout argument is -1), this
420  * function is a thin wrapper which calls \a User::WaitForAnyRequest()
421  * and \a CActiveScheduler::RunIfReady(). If the timeout value is
422  * specified, this function will schedule a timer entry to the timer
423  * heap (which is an Active Object), to limit the wait time for event
424  * occurences. Scheduling a timer entry is an expensive operation,
425  * therefore application should only specify a timeout value when it's
426  * really necessary (for example, when it's not sure there are other
427  * Active Objects currently running in the application).
428  *
429  * @param priority	The minimum priority of the Active Objects to
430  *			poll, which values are from CActive::TPriority
431  *			constants. If -1 is given, CActive::EPriorityStandard.
432  *			priority will be used.
433  * @param ms_timeout	Optional timeout to wait. Application should
434  *			specify -1 to let the function wait indefinitely
435  *			for any events.
436  *
437  * @return		PJ_TRUE if there have been any events executed
438  *			during the polling. This function will only return
439  *			PJ_FALSE if \a ms_timeout argument is specified
440  *			(i.e. the value is not -1) and there was no event
441  *			executed when the timeout timer elapsed.
442  */
443 PJ_DECL(pj_bool_t) pj_symbianos_poll(int priority, int ms_timeout);
444 
445 
446 /**
447  * This structure declares Symbian OS specific parameters that can be
448  * specified when calling #pj_symbianos_set_params().
449  */
450 typedef struct pj_symbianos_params
451 {
452     /**
453      * Optional RSocketServ instance to be used by PJLIB. If this
454      * value is NULL, PJLIB will create a new RSocketServ instance
455      * when pj_init() is called.
456      */
457     void	*rsocketserv;
458 
459     /**
460      * Optional RConnection instance to be used by PJLIB when creating
461      * sockets. If this value is NULL, no RConnection will be
462      * specified when creating sockets.
463      */
464     void	*rconnection;
465 
466     /**
467      * Optional RHostResolver instance to be used by PJLIB. If this value
468      * is NULL, a new RHostResolver instance will be created when
469      * pj_init() is called.
470      */
471     void 	*rhostresolver;
472 
473     /**
474      * Optional RHostResolver for IPv6 instance to be used by PJLIB.
475      * If this value is NULL, a new RHostResolver instance will be created
476      * when pj_init() is called.
477      */
478     void 	*rhostresolver6;
479 
480 } pj_symbianos_params;
481 
482 /**
483  * Specify Symbian OS parameters to be used by PJLIB. This function MUST
484  * be called before #pj_init() is called.
485  *
486  * @param prm		Symbian specific parameters.
487  *
488  * @return		PJ_SUCCESS if the parameters can be applied
489  *			successfully.
490  */
491 PJ_DECL(pj_status_t) pj_symbianos_set_params(pj_symbianos_params *prm);
492 
493 /**
494  *  Notify PJLIB that the access point connection has been down or unusable
495  *  and PJLIB should not try to access the Symbian socket API (especially ones
496  *  that send packets). Sending packet when RConnection is reconnected to
497  *  different access point may cause the WaitForRequest() for the function to
498  *  block indefinitely.
499  *
500  *  @param up		If set to PJ_FALSE it will cause PJLIB to not try
501  *  			to access socket API, and error will be returned
502  *  			immediately instead.
503  */
504 PJ_DECL(void) pj_symbianos_set_connection_status(pj_bool_t up);
505 
506 /**
507  * @}
508  */
509 
510 /* **************************************************************************/
511 /**
512  * @defgroup PJ_TLS Thread Local Storage.
513  * @ingroup PJ_OS
514  * @{
515  */
516 
517 /**
518  * Allocate thread local storage index. The initial value of the variable at
519  * the index is zero.
520  *
521  * @param index	    Pointer to hold the return value.
522  * @return	    PJ_SUCCESS on success, or the error code.
523  */
524 PJ_DECL(pj_status_t) pj_thread_local_alloc(long *index);
525 
526 /**
527  * Deallocate thread local variable.
528  *
529  * @param index	    The variable index.
530  */
531 PJ_DECL(void) pj_thread_local_free(long index);
532 
533 /**
534  * Set the value of thread local variable.
535  *
536  * @param index	    The index of the variable.
537  * @param value	    The value.
538  */
539 PJ_DECL(pj_status_t) pj_thread_local_set(long index, void *value);
540 
541 /**
542  * Get the value of thread local variable.
543  *
544  * @param index	    The index of the variable.
545  * @return	    The value.
546  */
547 PJ_DECL(void*) pj_thread_local_get(long index);
548 
549 
550 /**
551  * @}
552  */
553 
554 
555 /* **************************************************************************/
556 /**
557  * @defgroup PJ_ATOMIC Atomic Variables
558  * @ingroup PJ_OS
559  * @{
560  *
561  * This module provides API to manipulate atomic variables.
562  *
563  * \section pj_atomic_examples_sec Examples
564  *
565  * For some example codes, please see:
566  *  - @ref page_pjlib_atomic_test
567  */
568 
569 
570 /**
571  * Create atomic variable.
572  *
573  * @param pool	    The pool.
574  * @param initial   The initial value of the atomic variable.
575  * @param atomic    Pointer to hold the atomic variable upon return.
576  *
577  * @return	    PJ_SUCCESS on success, or the error code.
578  */
579 PJ_DECL(pj_status_t) pj_atomic_create( pj_pool_t *pool,
580 				       pj_atomic_value_t initial,
581 				       pj_atomic_t **atomic );
582 
583 /**
584  * Destroy atomic variable.
585  *
586  * @param atomic_var	the atomic variable.
587  *
588  * @return PJ_SUCCESS if success.
589  */
590 PJ_DECL(pj_status_t) pj_atomic_destroy( pj_atomic_t *atomic_var );
591 
592 /**
593  * Set the value of an atomic type, and return the previous value.
594  *
595  * @param atomic_var	the atomic variable.
596  * @param value		value to be set to the variable.
597  */
598 PJ_DECL(void) pj_atomic_set( pj_atomic_t *atomic_var,
599 			     pj_atomic_value_t value);
600 
601 /**
602  * Get the value of an atomic type.
603  *
604  * @param atomic_var	the atomic variable.
605  *
606  * @return the value of the atomic variable.
607  */
608 PJ_DECL(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var);
609 
610 /**
611  * Increment the value of an atomic type.
612  *
613  * @param atomic_var	the atomic variable.
614  */
615 PJ_DECL(void) pj_atomic_inc(pj_atomic_t *atomic_var);
616 
617 /**
618  * Increment the value of an atomic type and get the result.
619  *
620  * @param atomic_var	the atomic variable.
621  *
622  * @return              The incremented value.
623  */
624 PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var);
625 
626 /**
627  * Decrement the value of an atomic type.
628  *
629  * @param atomic_var	the atomic variable.
630  */
631 PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var);
632 
633 /**
634  * Decrement the value of an atomic type and get the result.
635  *
636  * @param atomic_var	the atomic variable.
637  *
638  * @return              The decremented value.
639  */
640 PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var);
641 
642 /**
643  * Add a value to an atomic type.
644  *
645  * @param atomic_var	The atomic variable.
646  * @param value		Value to be added.
647  */
648 PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var,
649 			     pj_atomic_value_t value);
650 
651 /**
652  * Add a value to an atomic type and get the result.
653  *
654  * @param atomic_var	The atomic variable.
655  * @param value		Value to be added.
656  *
657  * @return              The result after the addition.
658  */
659 PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
660 			                          pj_atomic_value_t value);
661 
662 /**
663  * @}
664  */
665 
666 /* **************************************************************************/
667 /**
668  * @defgroup PJ_MUTEX Mutexes.
669  * @ingroup PJ_OS
670  * @{
671  *
672  * Mutex manipulation. Alternatively, application can use higher abstraction
673  * for lock objects, which provides uniform API for all kinds of lock
674  * mechanisms, including mutex. See @ref PJ_LOCK for more information.
675  */
676 
677 /**
678  * Mutex types:
679  *  - PJ_MUTEX_DEFAULT: default mutex type, which is system dependent.
680  *  - PJ_MUTEX_SIMPLE: non-recursive mutex.
681  *  - PJ_MUTEX_RECURSE: recursive mutex.
682  */
683 typedef enum pj_mutex_type_e
684 {
685     PJ_MUTEX_DEFAULT,
686     PJ_MUTEX_SIMPLE,
687     PJ_MUTEX_RECURSE
688 } pj_mutex_type_e;
689 
690 
691 /**
692  * Create mutex of the specified type.
693  *
694  * @param pool	    The pool.
695  * @param name	    Name to be associated with the mutex (for debugging).
696  * @param type	    The type of the mutex, of type #pj_mutex_type_e.
697  * @param mutex	    Pointer to hold the returned mutex instance.
698  *
699  * @return	    PJ_SUCCESS on success, or the error code.
700  */
701 PJ_DECL(pj_status_t) pj_mutex_create(pj_pool_t *pool,
702                                      const char *name,
703 				     int type,
704                                      pj_mutex_t **mutex);
705 
706 /**
707  * Create simple, non-recursive mutex.
708  * This function is a simple wrapper for #pj_mutex_create to create
709  * non-recursive mutex.
710  *
711  * @param pool	    The pool.
712  * @param name	    Mutex name.
713  * @param mutex	    Pointer to hold the returned mutex instance.
714  *
715  * @return	    PJ_SUCCESS on success, or the error code.
716  */
717 PJ_DECL(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool, const char *name,
718 					     pj_mutex_t **mutex );
719 
720 /**
721  * Create recursive mutex.
722  * This function is a simple wrapper for #pj_mutex_create to create
723  * recursive mutex.
724  *
725  * @param pool	    The pool.
726  * @param name	    Mutex name.
727  * @param mutex	    Pointer to hold the returned mutex instance.
728  *
729  * @return	    PJ_SUCCESS on success, or the error code.
730  */
731 PJ_DECL(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
732 					        const char *name,
733 						pj_mutex_t **mutex );
734 
735 /**
736  * Acquire mutex lock.
737  *
738  * @param mutex	    The mutex.
739  * @return	    PJ_SUCCESS on success, or the error code.
740  */
741 PJ_DECL(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex);
742 
743 /**
744  * Release mutex lock.
745  *
746  * @param mutex	    The mutex.
747  * @return	    PJ_SUCCESS on success, or the error code.
748  */
749 PJ_DECL(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex);
750 
751 /**
752  * Try to acquire mutex lock.
753  *
754  * @param mutex	    The mutex.
755  * @return	    PJ_SUCCESS on success, or the error code if the
756  *		    lock couldn't be acquired.
757  */
758 PJ_DECL(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex);
759 
760 /**
761  * Destroy mutex.
762  *
763  * @param mutex	    Te mutex.
764  * @return	    PJ_SUCCESS on success, or the error code.
765  */
766 PJ_DECL(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex);
767 
768 /**
769  * Determine whether calling thread is owning the mutex (only available when
770  * PJ_DEBUG is set).
771  * @param mutex	    The mutex.
772  * @return	    Non-zero if yes.
773  */
774 PJ_DECL(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex);
775 
776 /**
777  * @}
778  */
779 
780 /* **************************************************************************/
781 /**
782  * @defgroup PJ_RW_MUTEX Reader/Writer Mutex
783  * @ingroup PJ_OS
784  * @{
785  * Reader/writer mutex is a classic synchronization object where multiple
786  * readers can acquire the mutex, but only a single writer can acquire the
787  * mutex.
788  */
789 
790 /**
791  * Opaque declaration for reader/writer mutex.
792  * Reader/writer mutex is a classic synchronization object where multiple
793  * readers can acquire the mutex, but only a single writer can acquire the
794  * mutex.
795  */
796 typedef struct pj_rwmutex_t pj_rwmutex_t;
797 
798 /**
799  * Create reader/writer mutex.
800  *
801  * @param pool	    Pool to allocate memory for the mutex.
802  * @param name	    Name to be assigned to the mutex.
803  * @param mutex	    Pointer to receive the newly created mutex.
804  *
805  * @return	    PJ_SUCCESS on success, or the error code.
806  */
807 PJ_DECL(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
808 				       pj_rwmutex_t **mutex);
809 
810 /**
811  * Lock the mutex for reading.
812  *
813  * @param mutex	    The mutex.
814  * @return	    PJ_SUCCESS on success, or the error code.
815  */
816 PJ_DECL(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex);
817 
818 /**
819  * Lock the mutex for writing.
820  *
821  * @param mutex	    The mutex.
822  * @return	    PJ_SUCCESS on success, or the error code.
823  */
824 PJ_DECL(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex);
825 
826 /**
827  * Release read lock.
828  *
829  * @param mutex	    The mutex.
830  * @return	    PJ_SUCCESS on success, or the error code.
831  */
832 PJ_DECL(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex);
833 
834 /**
835  * Release write lock.
836  *
837  * @param mutex	    The mutex.
838  * @return	    PJ_SUCCESS on success, or the error code.
839  */
840 PJ_DECL(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex);
841 
842 /**
843  * Destroy reader/writer mutex.
844  *
845  * @param mutex	    The mutex.
846  * @return	    PJ_SUCCESS on success, or the error code.
847  */
848 PJ_DECL(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex);
849 
850 
851 /**
852  * @}
853  */
854 
855 
856 /* **************************************************************************/
857 /**
858  * @defgroup PJ_CRIT_SEC Critical sections.
859  * @ingroup PJ_OS
860  * @{
861  * Critical section protection can be used to protect regions where:
862  *  - mutual exclusion protection is needed.
863  *  - it's rather too expensive to create a mutex.
864  *  - the time spent in the region is very very brief.
865  *
866  * Critical section is a global object, and it prevents any threads from
867  * entering any regions that are protected by critical section once a thread
868  * is already in the section.
869  *
870  * Critial section is \a not recursive!
871  *
872  * Application <b>MUST NOT</b> call any functions that may cause current
873  * thread to block (such as allocating memory, performing I/O, locking mutex,
874  * etc.) while holding the critical section.
875  */
876 /**
877  * Enter critical section.
878  */
879 PJ_DECL(void) pj_enter_critical_section(void);
880 
881 /**
882  * Leave critical section.
883  */
884 PJ_DECL(void) pj_leave_critical_section(void);
885 
886 /**
887  * @}
888  */
889 
890 /* **************************************************************************/
891 #if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
892 /**
893  * @defgroup PJ_SEM Semaphores.
894  * @ingroup PJ_OS
895  * @{
896  *
897  * This module provides abstraction for semaphores, where available.
898  */
899 
900 /**
901  * Create semaphore.
902  *
903  * @param pool	    The pool.
904  * @param name	    Name to be assigned to the semaphore (for logging purpose)
905  * @param initial   The initial count of the semaphore.
906  * @param max	    The maximum count of the semaphore.
907  * @param sem	    Pointer to hold the semaphore created.
908  *
909  * @return	    PJ_SUCCESS on success, or the error code.
910  */
911 PJ_DECL(pj_status_t) pj_sem_create( pj_pool_t *pool,
912                                     const char *name,
913 				    unsigned initial,
914                                     unsigned max,
915 				    pj_sem_t **sem);
916 
917 /**
918  * Wait for semaphore.
919  *
920  * @param sem	The semaphore.
921  *
922  * @return	PJ_SUCCESS on success, or the error code.
923  */
924 PJ_DECL(pj_status_t) pj_sem_wait(pj_sem_t *sem);
925 
926 /**
927  * Try wait for semaphore.
928  *
929  * @param sem	The semaphore.
930  *
931  * @return	PJ_SUCCESS on success, or the error code.
932  */
933 PJ_DECL(pj_status_t) pj_sem_trywait(pj_sem_t *sem);
934 
935 /**
936  * Release semaphore.
937  *
938  * @param sem	The semaphore.
939  *
940  * @return	PJ_SUCCESS on success, or the error code.
941  */
942 PJ_DECL(pj_status_t) pj_sem_post(pj_sem_t *sem);
943 
944 /**
945  * Destroy semaphore.
946  *
947  * @param sem	The semaphore.
948  *
949  * @return	PJ_SUCCESS on success, or the error code.
950  */
951 PJ_DECL(pj_status_t) pj_sem_destroy(pj_sem_t *sem);
952 
953 /**
954  * @}
955  */
956 #endif	/* PJ_HAS_SEMAPHORE */
957 
958 
959 /* **************************************************************************/
960 #if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0
961 /**
962  * @defgroup PJ_EVENT Event Object.
963  * @ingroup PJ_OS
964  * @{
965  *
966  * This module provides abstraction to event object (e.g. Win32 Event) where
967  * available. Event objects can be used for synchronization among threads.
968  */
969 
970 /**
971  * Create event object.
972  *
973  * @param pool		The pool.
974  * @param name		The name of the event object (for logging purpose).
975  * @param manual_reset	Specify whether the event is manual-reset
976  * @param initial	Specify the initial state of the event object.
977  * @param event		Pointer to hold the returned event object.
978  *
979  * @return event handle, or NULL if failed.
980  */
981 PJ_DECL(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
982 				     pj_bool_t manual_reset, pj_bool_t initial,
983 				     pj_event_t **event);
984 
985 /**
986  * Wait for event to be signaled.
987  *
988  * @param event	    The event object.
989  *
990  * @return zero if successfull.
991  */
992 PJ_DECL(pj_status_t) pj_event_wait(pj_event_t *event);
993 
994 /**
995  * Try wait for event object to be signalled.
996  *
997  * @param event The event object.
998  *
999  * @return zero if successfull.
1000  */
1001 PJ_DECL(pj_status_t) pj_event_trywait(pj_event_t *event);
1002 
1003 /**
1004  * Set the event object state to signaled. For auto-reset event, this
1005  * will only release the first thread that are waiting on the event. For
1006  * manual reset event, the state remains signaled until the event is reset.
1007  * If there is no thread waiting on the event, the event object state
1008  * remains signaled.
1009  *
1010  * @param event	    The event object.
1011  *
1012  * @return zero if successfull.
1013  */
1014 PJ_DECL(pj_status_t) pj_event_set(pj_event_t *event);
1015 
1016 /**
1017  * Set the event object to signaled state to release appropriate number of
1018  * waiting threads and then reset the event object to non-signaled. For
1019  * manual-reset event, this function will release all waiting threads. For
1020  * auto-reset event, this function will only release one waiting thread.
1021  *
1022  * @param event	    The event object.
1023  *
1024  * @return zero if successfull.
1025  */
1026 PJ_DECL(pj_status_t) pj_event_pulse(pj_event_t *event);
1027 
1028 /**
1029  * Set the event object state to non-signaled.
1030  *
1031  * @param event	    The event object.
1032  *
1033  * @return zero if successfull.
1034  */
1035 PJ_DECL(pj_status_t) pj_event_reset(pj_event_t *event);
1036 
1037 /**
1038  * Destroy the event object.
1039  *
1040  * @param event	    The event object.
1041  *
1042  * @return zero if successfull.
1043  */
1044 PJ_DECL(pj_status_t) pj_event_destroy(pj_event_t *event);
1045 
1046 /**
1047  * @}
1048  */
1049 #endif	/* PJ_HAS_EVENT_OBJ */
1050 
1051 /* **************************************************************************/
1052 /**
1053  * @addtogroup PJ_TIME Time Data Type and Manipulation.
1054  * @ingroup PJ_OS
1055  * @{
1056  * This module provides API for manipulating time.
1057  *
1058  * \section pj_time_examples_sec Examples
1059  *
1060  * For examples, please see:
1061  *  - \ref page_pjlib_sleep_test
1062  */
1063 
1064 /**
1065  * Get current time of day in local representation.
1066  *
1067  * @param tv	Variable to store the result.
1068  *
1069  * @return zero if successfull.
1070  */
1071 PJ_DECL(pj_status_t) pj_gettimeofday(pj_time_val *tv);
1072 
1073 
1074 /**
1075  * Parse time value into date/time representation.
1076  *
1077  * @param tv	The time.
1078  * @param pt	Variable to store the date time result.
1079  *
1080  * @return zero if successfull.
1081  */
1082 PJ_DECL(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt);
1083 
1084 /**
1085  * Encode date/time to time value.
1086  *
1087  * @param pt	The date/time.
1088  * @param tv	Variable to store time value result.
1089  *
1090  * @return zero if successfull.
1091  */
1092 PJ_DECL(pj_status_t) pj_time_encode(const pj_parsed_time *pt, pj_time_val *tv);
1093 
1094 /**
1095  * Convert local time to GMT.
1096  *
1097  * @param tv	Time to convert.
1098  *
1099  * @return zero if successfull.
1100  */
1101 PJ_DECL(pj_status_t) pj_time_local_to_gmt(pj_time_val *tv);
1102 
1103 /**
1104  * Convert GMT to local time.
1105  *
1106  * @param tv	Time to convert.
1107  *
1108  * @return zero if successfull.
1109  */
1110 PJ_DECL(pj_status_t) pj_time_gmt_to_local(pj_time_val *tv);
1111 
1112 /**
1113  * @}
1114  */
1115 
1116 /* **************************************************************************/
1117 #if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
1118 
1119 /**
1120  * @defgroup PJ_TERM Terminal
1121  * @ingroup PJ_OS
1122  * @{
1123  */
1124 
1125 /**
1126  * Set current terminal color.
1127  *
1128  * @param color	    The RGB color.
1129  *
1130  * @return zero on success.
1131  */
1132 PJ_DECL(pj_status_t) pj_term_set_color(pj_color_t color);
1133 
1134 /**
1135  * Get current terminal foreground color.
1136  *
1137  * @return RGB color.
1138  */
1139 PJ_DECL(pj_color_t) pj_term_get_color(void);
1140 
1141 /**
1142  * @}
1143  */
1144 
1145 #endif	/* PJ_TERM_HAS_COLOR */
1146 
1147 /* **************************************************************************/
1148 /**
1149  * @defgroup PJ_TIMESTAMP High Resolution Timestamp
1150  * @ingroup PJ_OS
1151  * @{
1152  *
1153  * PJLIB provides <b>High Resolution Timestamp</b> API to access highest
1154  * resolution timestamp value provided by the platform. The API is usefull
1155  * to measure precise elapsed time, and can be used in applications such
1156  * as profiling.
1157  *
1158  * The timestamp value is represented in cycles, and can be related to
1159  * normal time (in seconds or sub-seconds) using various functions provided.
1160  *
1161  * \section pj_timestamp_examples_sec Examples
1162  *
1163  * For examples, please see:
1164  *  - \ref page_pjlib_sleep_test
1165  *  - \ref page_pjlib_timestamp_test
1166  */
1167 
1168 /*
1169  * High resolution timer.
1170  */
1171 #if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
1172 
1173 /**
1174  * Get monotonic time since some unspecified starting point.
1175  *
1176  * @param tv	Variable to store the result.
1177  *
1178  * @return PJ_SUCCESS if successful.
1179  */
1180 PJ_DECL(pj_status_t) pj_gettickcount(pj_time_val *tv);
1181 
1182 /**
1183  * Acquire high resolution timer value. The time value are stored
1184  * in cycles.
1185  *
1186  * @param ts	    High resolution timer value.
1187  * @return	    PJ_SUCCESS or the appropriate error code.
1188  *
1189  * @see pj_get_timestamp_freq().
1190  */
1191 PJ_DECL(pj_status_t) pj_get_timestamp(pj_timestamp *ts);
1192 
1193 /**
1194  * Get high resolution timer frequency, in cycles per second.
1195  *
1196  * @param freq	    Timer frequency, in cycles per second.
1197  * @return	    PJ_SUCCESS or the appropriate error code.
1198  */
1199 PJ_DECL(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq);
1200 
1201 /**
1202  * Set timestamp from 32bit values.
1203  * @param t	    The timestamp to be set.
1204  * @param hi	    The high 32bit part.
1205  * @param lo	    The low 32bit part.
1206  */
pj_set_timestamp32(pj_timestamp * t,pj_uint32_t hi,pj_uint32_t lo)1207 PJ_INLINE(void) pj_set_timestamp32(pj_timestamp *t, pj_uint32_t hi,
1208 				   pj_uint32_t lo)
1209 {
1210     t->u32.hi = hi;
1211     t->u32.lo = lo;
1212 }
1213 
1214 
1215 /**
1216  * Compare timestamp t1 and t2.
1217  * @param t1	    t1.
1218  * @param t2	    t2.
1219  * @return	    -1 if (t1 < t2), 1 if (t1 > t2), or 0 if (t1 == t2)
1220  */
pj_cmp_timestamp(const pj_timestamp * t1,const pj_timestamp * t2)1221 PJ_INLINE(int) pj_cmp_timestamp(const pj_timestamp *t1, const pj_timestamp *t2)
1222 {
1223 #if PJ_HAS_INT64
1224     if (t1->u64 < t2->u64)
1225 	return -1;
1226     else if (t1->u64 > t2->u64)
1227 	return 1;
1228     else
1229 	return 0;
1230 #else
1231     if (t1->u32.hi < t2->u32.hi ||
1232 	(t1->u32.hi == t2->u32.hi && t1->u32.lo < t2->u32.lo))
1233 	return -1;
1234     else if (t1->u32.hi > t2->u32.hi ||
1235 	     (t1->u32.hi == t2->u32.hi && t1->u32.lo > t2->u32.lo))
1236 	return 1;
1237     else
1238 	return 0;
1239 #endif
1240 }
1241 
1242 
1243 /**
1244  * Add timestamp t2 to t1.
1245  * @param t1	    t1.
1246  * @param t2	    t2.
1247  */
pj_add_timestamp(pj_timestamp * t1,const pj_timestamp * t2)1248 PJ_INLINE(void) pj_add_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1249 {
1250 #if PJ_HAS_INT64
1251     t1->u64 += t2->u64;
1252 #else
1253     pj_uint32_t old = t1->u32.lo;
1254     t1->u32.hi += t2->u32.hi;
1255     t1->u32.lo += t2->u32.lo;
1256     if (t1->u32.lo < old)
1257 	++t1->u32.hi;
1258 #endif
1259 }
1260 
1261 /**
1262  * Add timestamp t2 to t1.
1263  * @param t1	    t1.
1264  * @param t2	    t2.
1265  */
pj_add_timestamp32(pj_timestamp * t1,pj_uint32_t t2)1266 PJ_INLINE(void) pj_add_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1267 {
1268 #if PJ_HAS_INT64
1269     t1->u64 += t2;
1270 #else
1271     pj_uint32_t old = t1->u32.lo;
1272     t1->u32.lo += t2;
1273     if (t1->u32.lo < old)
1274 	++t1->u32.hi;
1275 #endif
1276 }
1277 
1278 /**
1279  * Substract timestamp t2 from t1.
1280  * @param t1	    t1.
1281  * @param t2	    t2.
1282  */
pj_sub_timestamp(pj_timestamp * t1,const pj_timestamp * t2)1283 PJ_INLINE(void) pj_sub_timestamp(pj_timestamp *t1, const pj_timestamp *t2)
1284 {
1285 #if PJ_HAS_INT64
1286     t1->u64 -= t2->u64;
1287 #else
1288     t1->u32.hi -= t2->u32.hi;
1289     if (t1->u32.lo >= t2->u32.lo)
1290 	t1->u32.lo -= t2->u32.lo;
1291     else {
1292 	t1->u32.lo -= t2->u32.lo;
1293 	--t1->u32.hi;
1294     }
1295 #endif
1296 }
1297 
1298 /**
1299  * Substract timestamp t2 from t1.
1300  * @param t1	    t1.
1301  * @param t2	    t2.
1302  */
pj_sub_timestamp32(pj_timestamp * t1,pj_uint32_t t2)1303 PJ_INLINE(void) pj_sub_timestamp32(pj_timestamp *t1, pj_uint32_t t2)
1304 {
1305 #if PJ_HAS_INT64
1306     t1->u64 -= t2;
1307 #else
1308     if (t1->u32.lo >= t2)
1309 	t1->u32.lo -= t2;
1310     else {
1311 	t1->u32.lo -= t2;
1312 	--t1->u32.hi;
1313     }
1314 #endif
1315 }
1316 
1317 /**
1318  * Get the timestamp difference between t2 and t1 (that is t2 minus t1),
1319  * and return a 32bit signed integer difference.
1320  */
pj_timestamp_diff32(const pj_timestamp * t1,const pj_timestamp * t2)1321 PJ_INLINE(pj_int32_t) pj_timestamp_diff32(const pj_timestamp *t1,
1322 					  const pj_timestamp *t2)
1323 {
1324     /* Be careful with the signess (I think!) */
1325 #if PJ_HAS_INT64
1326     pj_int64_t diff = t2->u64 - t1->u64;
1327     return (pj_int32_t) diff;
1328 #else
1329     pj_int32 diff = t2->u32.lo - t1->u32.lo;
1330     return diff;
1331 #endif
1332 }
1333 
1334 
1335 /**
1336  * Calculate the elapsed time, and store it in pj_time_val.
1337  * This function calculates the elapsed time using highest precision
1338  * calculation that is available for current platform, considering
1339  * whether floating point or 64-bit precision arithmetic is available.
1340  * For maximum portability, application should prefer to use this function
1341  * rather than calculating the elapsed time by itself.
1342  *
1343  * @param start     The starting timestamp.
1344  * @param stop      The end timestamp.
1345  *
1346  * @return	    Elapsed time as #pj_time_val.
1347  *
1348  * @see pj_elapsed_usec(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1349  */
1350 PJ_DECL(pj_time_val) pj_elapsed_time( const pj_timestamp *start,
1351                                       const pj_timestamp *stop );
1352 
1353 /**
1354  * Calculate the elapsed time as 32-bit miliseconds.
1355  * This function calculates the elapsed time using highest precision
1356  * calculation that is available for current platform, considering
1357  * whether floating point or 64-bit precision arithmetic is available.
1358  * For maximum portability, application should prefer to use this function
1359  * rather than calculating the elapsed time by itself.
1360  *
1361  * @param start     The starting timestamp.
1362  * @param stop      The end timestamp.
1363  *
1364  * @return	    Elapsed time in milisecond.
1365  *
1366  * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1367  */
1368 PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start,
1369                                       const pj_timestamp *stop );
1370 
1371 /**
1372  * Variant of #pj_elapsed_msec() which returns 64bit value.
1373  */
1374 PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start,
1375                                        const pj_timestamp *stop );
1376 
1377 /**
1378  * Calculate the elapsed time in 32-bit microseconds.
1379  * This function calculates the elapsed time using highest precision
1380  * calculation that is available for current platform, considering
1381  * whether floating point or 64-bit precision arithmetic is available.
1382  * For maximum portability, application should prefer to use this function
1383  * rather than calculating the elapsed time by itself.
1384  *
1385  * @param start     The starting timestamp.
1386  * @param stop      The end timestamp.
1387  *
1388  * @return	    Elapsed time in microsecond.
1389  *
1390  * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec()
1391  */
1392 PJ_DECL(pj_uint32_t) pj_elapsed_usec( const pj_timestamp *start,
1393                                       const pj_timestamp *stop );
1394 
1395 /**
1396  * Calculate the elapsed time in 32-bit nanoseconds.
1397  * This function calculates the elapsed time using highest precision
1398  * calculation that is available for current platform, considering
1399  * whether floating point or 64-bit precision arithmetic is available.
1400  * For maximum portability, application should prefer to use this function
1401  * rather than calculating the elapsed time by itself.
1402  *
1403  * @param start     The starting timestamp.
1404  * @param stop      The end timestamp.
1405  *
1406  * @return	    Elapsed time in nanoseconds.
1407  *
1408  * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_usec()
1409  */
1410 PJ_DECL(pj_uint32_t) pj_elapsed_nanosec( const pj_timestamp *start,
1411                                          const pj_timestamp *stop );
1412 
1413 /**
1414  * Calculate the elapsed time in 32-bit cycles.
1415  * This function calculates the elapsed time using highest precision
1416  * calculation that is available for current platform, considering
1417  * whether floating point or 64-bit precision arithmetic is available.
1418  * For maximum portability, application should prefer to use this function
1419  * rather than calculating the elapsed time by itself.
1420  *
1421  * @param start     The starting timestamp.
1422  * @param stop      The end timestamp.
1423  *
1424  * @return	    Elapsed time in cycles.
1425  *
1426  * @see pj_elapsed_usec(), pj_elapsed_time(), pj_elapsed_nanosec()
1427  */
1428 PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
1429                                        const pj_timestamp *stop );
1430 
1431 
1432 #endif	/* PJ_HAS_HIGH_RES_TIMER */
1433 
1434 /** @} */
1435 
1436 
1437 /* **************************************************************************/
1438 /**
1439  * @defgroup PJ_APP_OS Application execution
1440  * @ingroup PJ_OS
1441  * @{
1442  */
1443 
1444 /**
1445  * Type for application main function.
1446  */
1447 typedef int (*pj_main_func_ptr)(int argc, char *argv[]);
1448 
1449 /**
1450  * Run the application. This function has to be called in the main thread
1451  * and after doing the necessary initialization according to the flags
1452  * provided, it will call main_func() function.
1453  *
1454  * @param main_func Application's main function.
1455  * @param argc	    Number of arguments from the main() function, which
1456  * 		    will be passed to main_func() function.
1457  * @param argv	    The arguments from the main() function, which will
1458  * 		    be passed to main_func() function.
1459  * @param flags     Flags for application execution, currently must be 0.
1460  *
1461  * @return          main_func()'s return value.
1462  */
1463 PJ_DECL(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
1464 			unsigned flags);
1465 
1466 /** @} */
1467 
1468 
1469 /* **************************************************************************/
1470 /**
1471  * Internal PJLIB function to initialize the threading subsystem.
1472  * @return          PJ_SUCCESS or the appropriate error code.
1473  */
1474 pj_status_t pj_thread_init(void);
1475 
1476 
1477 PJ_END_DECL
1478 
1479 #endif  /* __PJ_OS_H__ */
1480 
1481