From 39b4b3d3bb933da80b4f80fb4561f031456fe8d1 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Fri, 25 Aug 2006 12:41:05 +0000 Subject: Yet another documentation/doxygen update git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@691 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/docs/doxygen.cfg | 2 +- pjlib/docs/footer.html | 2 +- pjlib/include/pj/doxygen.h | 2 +- pjlib/include/pj/ioqueue.h | 2 +- pjlib/include/pj/pool.h | 304 ++++++++++++++++++++++++++++++++-------- pjsip/include/pjsua-lib/pjsua.h | 17 +++ 6 files changed, 267 insertions(+), 62 deletions(-) diff --git a/pjlib/docs/doxygen.cfg b/pjlib/docs/doxygen.cfg index d167fdb4..d8956325 100644 --- a/pjlib/docs/doxygen.cfg +++ b/pjlib/docs/doxygen.cfg @@ -17,7 +17,7 @@ # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = "PJLIB Open Source" +PROJECT_NAME = "PJLIB Reference" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or diff --git a/pjlib/docs/footer.html b/pjlib/docs/footer.html index 2c7f93aa..9965d35c 100644 --- a/pjlib/docs/footer.html +++ b/pjlib/docs/footer.html @@ -1,7 +1,7 @@

 


PJLIB Open Source, high performance, small footprint, and very very portable framework
-(C)2003-2006 Benny Prijono +(C)2001-2006 Benny Prijono
diff --git a/pjlib/include/pj/doxygen.h b/pjlib/include/pj/doxygen.h index 95ba72e5..51a69777 100644 --- a/pjlib/include/pj/doxygen.h +++ b/pjlib/include/pj/doxygen.h @@ -393,7 +393,7 @@ * * Enjoy using PJLIB! * - * Benny Prijono < bennylp at pjproject dot net > + * Benny Prijono < bennylp at pjsip dot org > */ diff --git a/pjlib/include/pj/ioqueue.h b/pjlib/include/pj/ioqueue.h index 0f77f6f6..8afe1ce3 100644 --- a/pjlib/include/pj/ioqueue.h +++ b/pjlib/include/pj/ioqueue.h @@ -59,7 +59,7 @@ PJ_BEGIN_DECL */ /** - * @defgroup PJ_IOQUEUE I/O Event Dispatching Queue + * @defgroup PJ_IOQUEUE IOQueue: I/O Event Dispatching with Proactor Pattern * @ingroup PJ_IO * @{ * diff --git a/pjlib/include/pj/pool.h b/pjlib/include/pj/pool.h index 34076099..48c00e8e 100644 --- a/pjlib/include/pj/pool.h +++ b/pjlib/include/pj/pool.h @@ -38,60 +38,235 @@ PJ_BEGIN_DECL /** - * @defgroup PJ_POOL_GROUP Memory Pool Management + * @defgroup PJ_POOL_GROUP Fast Memory Pool * @ingroup PJ * @brief - * Memory pool management provides API to allocate and deallocate memory from - * memory pool and to manage and establish policy for pool creation and - * destruction in pool factory. + * Memory pools allow dynamic memory allocation comparable to malloc or the + * new in operator C++. Those implementations are not desirable for very + * high performance applications or real-time systems, because of the + * performance bottlenecks and it suffers from fragmentation issue. * - * \section PJ_POOL_FACTORY_SEC Pool Factory - * See: \ref PJ_POOL_FACTORY "Pool Factory" - * - * A memory pool must be created through a factory. A factory not only provides - * generic interface functions to create and release pool, but also provides - * strategy to manage the life time of pools. One sample implementation, - * \a pj_caching_pool, can be set to keep the pools released by application for - * future use as long as the total memory is below the limit. + * \section PJ_POOL_INTRO_SEC PJLIB's Memory Pool + * \subsection PJ_POOL_ADVANTAGE_SUBSEC Advantages * - * The pool factory interface declared in PJLIB is designed to be extensible. - * Application can define its own strategy by creating it's own pool factory - * implementation, and this strategy can be used even by existing library - * without recompilation. + * PJLIB's pool has many advantages over traditional malloc/new operator and + * over other memory pool implementations, because: + * - unlike other memory pool implementation, it allows allocation of + * memory chunks of different sizes, + * - it's very very fast. + * \n + * Memory chunk allocation is not only an O(1) + * operation, but it's also very simple (just + * few pointer arithmetic operations) and it doesn't require locking + * any mutex, + * - it's memory efficient. + * \n + * Pool doesn't keep track individual memory chunks allocated by + * applications, so there is no additional overhead needed for each + * memory allocation (other than possible additional of few bytes, up to + * PJ_POOL_ALIGNMENT-1, for aligning the memory). + * But see the @ref PJ_POOL_CAVEATS_SUBSEC below. + * - it prevents memory leaks. + * \n + * Memory pool inherently has garbage collection functionality. In fact, + * there is no need to free the chunks allocated from the memory pool. + * All chunks previously allocated from the pool will be freed once the + * pool itself is destroyed. This would prevent memory leaks that haunt + * programmers for decades, and it provides additional performance + * advantage over traditional malloc/new operator. + * + * Even more, PJLIB's memory pool provides some additional usability and + * flexibility for applications: + * - memory leaks are easily traceable, since memory pool is assigned name, + * and application can inspect what pools currently active in the system. + * - by design, memory allocation from a pool is not thread safe. We assumed + * that a pool will be owned by a higher level object, and thread safety + * should be handled by that object. This enables very fast pool operations + * and prevents unnecessary locking operations, + * - by default, the memory pool API behaves more like C++ new operator, + * in that it will throw PJ_NO_MEMORY_EXCEPTION exception (see + * @ref PJ_EXCEPT) when memory chunk allocation fails. This enables failure + * handling to be done on more high level function (instead of checking + * the result of pj_pool_alloc() everytime). If application doesn't like + * this, the default behavior can be changed on global basis by supplying + * different policy to the pool factory. + * - any memory allocation backend allocator/deallocator may be used. By + * default, the policy uses malloc() and free() to manage the pool's block, + * but application may use different strategy, for example to allocate + * memory blocks from a globally static memory location. + * + * + * \subsection PJ_POOL_PERFORMANCE_SUBSEC Performance + * + * The result of PJLIB's memory design and careful implementation is a + * memory allocation strategy that can speed-up the memory allocations + * and deallocations by up to 30 times compared to standard + * malloc()/free()! + * + * (Note: your mileage may vary, of course. You can see how much PJLIB's + * pool improves the performance over malloc()/free() in your target + * system by running pjlib-test application). * * - * \section PJ_POOL_POLICY_SEC Pool Factory Policy - * See: \ref PJ_POOL_FACTORY "Pool Factory Policy" + * \subsection PJ_POOL_CAVEATS_SUBSEC Caveats * - * A pool factory only defines functions to create and release pool and how - * to manage pools, but the rest of the functionalities are controlled by - * policy. A pool policy defines: - * - how memory block is allocated and deallocated (the default implementation - * allocates and deallocate memory by calling malloc() and free()). - * - callback to be called when memory allocation inside a pool fails (the - * default implementation will throw PJ_NO_MEMORY_EXCEPTION exception). - * - concurrency when creating and releasing pool from/to the factory. + * There are some caveats though! * - * A pool factory can be given different policy during creation to make - * it behave differently. For example, caching pool factory can be configured - * to allocate and deallocate from a static/contiguous/preallocated memory - * instead of using malloc()/free(). - * - * What strategy/factory and what policy to use is not defined by PJLIB, but - * instead is left to application to make use whichever is most efficient for - * itself. + * When creating pool, PJLIB requires applications to specify the initial + * pool size, and as soon as the pool is created, PJLIB allocates memory + * from the system by that size. Application designers MUST choose the + * initial pool size carefully, since choosing too big value will result in + * wasting system's memory. + * + * But the pool can grow. Application designer can specify how the + * pool will grow in size, by specifying the size increment when creating + * the pool. + * + * The pool, however, cannot shrink! Since there is no + * function to deallocate memory chunks, there is no way for the pool to + * release back unused memory to the system. + * Application designers must be aware that constant memory allocations + * from pool that has infinite life-time may cause the memory usage of + * the application to grow over time. + * + * + * \section PJ_POOL_USING_SEC Using Memory Pool + * + * This section describes how to use PJLIB's memory pool framework. + * As we hope the readers will witness, PJLIB's memory pool API is quite + * straightforward. * + * \subsection PJ_POOL_USING_F Create Pool Factory + * First, application needs to initialize a pool factory (this normally + * only needs to be done once in one application). PJLIB provides + * a pool factory implementation called caching pool (see @ref + * PJ_CACHING_POOL), and it is initialized by calling #pj_caching_pool_init(). * - * \section PJ_POOL_POOL_SEC The Pool - * See: \ref PJ_POOL "Pool" + * \subsection PJ_POOL_USING_P Create The Pool + * Then application creates the pool object itself with #pj_pool_create(), + * specifying among other thing the pool factory where the pool should + * be created from, the pool name, initial size, and increment/expansion + * size. * + * \subsection PJ_POOL_USING_M Allocate Memory as Required + * Then whenever application needs to allocate dynamic memory, it would + * call #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc() to + * allocate memory chunks from the pool. + * + * \subsection PJ_POOL_USING_DP Destroy the Pool + * When application has finished with the pool, it should call + * #pj_pool_release() to release the pool object back to the factory. + * Depending on the types of the factory, this may release the memory back + * to the operating system. + * + * \subsection PJ_POOL_USING_Dc Destroy the Pool Factory + * And finally, before application quites, it should deinitialize the + * pool factory, to make sure that all memory blocks allocated by the + * factory are released back to the operating system. After this, of + * course no more memory pool allocation can be requested. + * + * \subsection PJ_POOL_USING_EX Example + * Below is a sample complete program that utilizes PJLIB's memory pool. + * + * \code + + #include + + #define THIS_FILE "pool_sample.c" + + static void my_perror(const char *title, pj_status_t status) + { + char errmsg[PJ_ERR_MSG_SIZE]; + + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(1,(THIS_FILE, "%s: %s [status=%d]", title, errmsg, status)); + } + + static void pool_demo_1(pj_pool_factory *pfactory) + { + unsigned i; + pj_pool_t *pool; + + // Must create pool before we can allocate anything + pool = pj_pool_create(pfactory, // the factory + "pool1", // pool's name + 4000, // initial size + 4000, // increment size + NULL); // use default callback. + if (pool == NULL) { + my_perror("Error creating pool", PJ_ENOMEM); + return; + } + + // Demo: allocate some memory chunks + for (i=0; i<1000; ++i) { + void *p; + + p = pj_pool_alloc(pool, (pj_rand()+1) % 512); + + // Do something with p + ... + + // Look! No need to free p!! + } + + // Done with silly demo, must free pool to release all memory. + pj_pool_release(pool); + } + + int main() + { + pj_caching_pool cp; + pj_status_t status; + + // Must init PJLIB before anything else + status = pj_init(); + if (status != PJ_SUCCESS) { + my_perror("Error initializing PJLIB", status); + return 1; + } + + // Create the pool factory, in this case, a caching pool. + pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, + 1024*1024 ); + + // Do a demo + pool_demo_1(&cp.factory); + + // Done with demos, destroy caching pool before exiting app. + pj_caching_pool_destroy(&cp); + + return 0; + } + + \endcode + * + * More information about pool factory, the pool object, and caching pool + * can be found on the Module Links below. + */ + + +/** + * @defgroup PJ_POOL Memory Pool Object + * @ingroup PJ_POOL_GROUP + * @brief * The memory pool is an opaque object created by pool factory. * Application uses this object to request a memory chunk, by calling - * #pj_pool_alloc or #pj_pool_calloc. When the application has finished using - * the pool, it must call #pj_pool_release to free all the chunks previously + * #pj_pool_alloc(), #pj_pool_calloc(), or #pj_pool_zalloc(). + * When the application has finished using + * the pool, it must call #pj_pool_release() to free all the chunks previously * allocated and release the pool back to the factory. * - * \section PJ_POOL_THREADING_SEC More on Threading Policies: + * A memory pool is initialized with an initial amount of memory, which is + * called a block. Pool can be configured to dynamically allocate more memory + * blocks when it runs out of memory. + * + * The pool doesn't keep track of individual memory allocations + * by user, and the user doesn't have to free these indidual allocations. This + * makes memory allocation simple and very fast. All the memory allocated from + * the pool will be destroyed when the pool itself is destroyed. + * + * \section PJ_POOL_THREADING_SEC More on Threading Policies * - By design, memory allocation from a pool is not thread safe. We assumed * that a pool will be owned by an object, and thread safety should be * handled by that object. Thus these functions are not thread safe: @@ -105,20 +280,7 @@ PJ_BEGIN_DECL * * For some sample codes on how to use the pool, please see: * - @ref page_pjlib_pool_test - */ - -/** - * @defgroup PJ_POOL Memory Pool. - * @ingroup PJ_POOL_GROUP - * @brief - * A memory pool is initialized with an initial amount of memory, which is - * called a block. Pool can be configured to dynamically allocate more memory - * blocks when it runs out of memory. Subsequent memory allocations by user - * will use up portions of these block. - * The pool doesn't keep track of individual memory allocations - * by user, and the user doesn't have to free these indidual allocations. This - * makes memory allocation simple and very fast. All the memory allocated from - * the pool will be destroyed when the pool itself is destroyed. + * * @{ */ @@ -314,12 +476,19 @@ PJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, /* **************************************************************************/ /** - * @defgroup PJ_POOL_FACTORY Pool Factory and Policy. + * @defgroup PJ_POOL_FACTORY Pool Factory and Policy * @ingroup PJ_POOL_GROUP * @brief - * Pool factory declares an interface to create and destroy pool. There may - * be several strategies for pool creation, and these strategies should - * implement the interface defined by pool factory. + * A pool object must be created through a factory. A factory not only provides + * generic interface functions to create and release pool, but also provides + * strategy to manage the life time of pools. One sample implementation, + * \a pj_caching_pool, can be set to keep the pools released by application for + * future use as long as the total memory is below the limit. + * + * The pool factory interface declared in PJLIB is designed to be extensible. + * Application can define its own strategy by creating it's own pool factory + * implementation, and this strategy can be used even by existing library + * without recompilation. * * \section PJ_POOL_FACTORY_ITF Pool Factory Interface * The pool factory defines the following interface: @@ -328,6 +497,25 @@ PJ_IDECL(void*) pj_pool_calloc( pj_pool_t *pool, pj_size_t count, * - \a release_pool(): release memory pool back to factory. * * \section PJ_POOL_FACTORY_POL Pool Factory Policy. + * + * A pool factory only defines functions to create and release pool and how + * to manage pools, but the rest of the functionalities are controlled by + * policy. A pool policy defines: + * - how memory block is allocated and deallocated (the default implementation + * allocates and deallocate memory by calling malloc() and free()). + * - callback to be called when memory allocation inside a pool fails (the + * default implementation will throw PJ_NO_MEMORY_EXCEPTION exception). + * - concurrency when creating and releasing pool from/to the factory. + * + * A pool factory can be given different policy during creation to make + * it behave differently. For example, caching pool factory can be configured + * to allocate and deallocate from a static/contiguous/preallocated memory + * instead of using malloc()/free(). + * + * What strategy/factory and what policy to use is not defined by PJLIB, but + * instead is left to application to make use whichever is most efficient for + * itself. + * * The pool factory policy controls the behaviour of memory factories, and * defines the following interface: * - \a block_alloc(): allocate memory block from backend memory mgmt/system. @@ -529,7 +717,7 @@ PJ_INLINE(void) pj_pool_factory_dump( pj_pool_factory *pf, /* **************************************************************************/ /** - * @defgroup PJ_CACHING_POOL Caching Pool Factory. + * @defgroup PJ_CACHING_POOL Caching Pool Factory * @ingroup PJ_POOL_GROUP * @brief * Caching pool is one sample implementation of pool factory where the diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index d2ca7a34..1fbcd2f3 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -2516,6 +2516,23 @@ PJ_DECL(pj_status_t) pjsua_enum_snd_devs(pjmedia_snd_dev_info info[], unsigned *count); + +/** + * Get currently active sound devices. If sound devices has not been created + * (for example when pjsua_start() is not called), it is possible that + * the function returns PJ_SUCCESS with -1 as device IDs. + * + * @param capture_dev On return it will be filled with device ID of the + * capture device. + * @param playback_dev On return it will be filled with device ID of the + * device ID of the playback device. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsua_get_snd_dev(int *capture_dev, + int *playback_dev); + + /** * Select or change sound device. Application may call this function at * any time to replace current sound device. -- cgit v1.2.3