Changeset 36 for pjproject


Ignore:
Timestamp:
Nov 9, 2005 3:37:19 PM (19 years ago)
Author:
bennylp
Message:

Rework pjlib++

Location:
pjproject/main/pjlib
Files:
5 added
2 deleted
24 edited
2 moved

Legend:

Unmodified
Added
Removed
  • pjproject/main/pjlib/build/pjlib++.dsp

    r35 r36  
    1 # Microsoft Developer Studio Project File - Name="pjlibpp" - Package Owner=<4> 
     1# Microsoft Developer Studio Project File - Name="pjlib++" - Package Owner=<4> 
    22# Microsoft Developer Studio Generated Build File, Format Version 6.00 
    33# ** DO NOT EDIT ** 
     
    55# TARGTYPE "Win32 (x86) Static Library" 0x0104 
    66 
    7 CFG=pjlibpp - Win32 Debug 
     7CFG=pjlib++ - Win32 Debug 
    88!MESSAGE This is not a valid makefile. To build this project using NMAKE, 
    99!MESSAGE use the Export Makefile command and run 
    1010!MESSAGE  
    11 !MESSAGE NMAKE /f "pjlibpp.mak". 
     11!MESSAGE NMAKE /f "pjlib++.mak". 
    1212!MESSAGE  
    1313!MESSAGE You can specify a configuration when running NMAKE 
    1414!MESSAGE by defining the macro CFG on the command line. For example: 
    1515!MESSAGE  
    16 !MESSAGE NMAKE /f "pjlibpp.mak" CFG="pjlibpp - Win32 Debug" 
     16!MESSAGE NMAKE /f "pjlib++.mak" CFG="pjlib++ - Win32 Debug" 
    1717!MESSAGE  
    1818!MESSAGE Possible choices for configuration are: 
    1919!MESSAGE  
    20 !MESSAGE "pjlibpp - Win32 Release" (based on "Win32 (x86) Static Library") 
    21 !MESSAGE "pjlibpp - Win32 Debug" (based on "Win32 (x86) Static Library") 
     20!MESSAGE "pjlib++ - Win32 Release" (based on "Win32 (x86) Static Library") 
     21!MESSAGE "pjlib++ - Win32 Debug" (based on "Win32 (x86) Static Library") 
    2222!MESSAGE  
    2323 
     
    2929RSC=rc.exe 
    3030 
    31 !IF  "$(CFG)" == "pjlibpp - Win32 Release" 
     31!IF  "$(CFG)" == "pjlib++ - Win32 Release" 
    3232 
    3333# PROP BASE Use_MFC 0 
    3434# PROP BASE Use_Debug_Libraries 0 
    35 # PROP BASE Output_Dir ".\output\pjlibpp-i386-win32-vc6-release" 
    36 # PROP BASE Intermediate_Dir ".\output\pjlibpp-i386-win32-vc6-release" 
     35# PROP BASE Output_Dir ".\output\pjlib++-i386-win32-vc6-release" 
     36# PROP BASE Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-release" 
    3737# PROP BASE Target_Dir "" 
    3838# PROP Use_MFC 0 
    3939# PROP Use_Debug_Libraries 0 
    40 # PROP Output_Dir ".\output\pjlibpp-i386-win32-vc6-release" 
    41 # PROP Intermediate_Dir ".\output\pjlibpp-i386-win32-vc6-release" 
     40# PROP Output_Dir ".\output\pjlib++-i386-win32-vc6-release" 
     41# PROP Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-release" 
    4242# PROP Target_Dir "" 
    4343# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 
    44 # ADD CPP /nologo /MD /W3 /GX /O2 /I "../src" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PJ_WIN32" /D "PJ_M_I386" /FD /c 
     44# ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FD /c 
    4545# SUBTRACT CPP /YX 
    4646# ADD BASE RSC /l 0x409 /d "NDEBUG" 
     
    5353# ADD LIB32 /nologo /out:"../lib/pjlibp_vc6s.lib" 
    5454 
    55 !ELSEIF  "$(CFG)" == "pjlibpp - Win32 Debug" 
     55!ELSEIF  "$(CFG)" == "pjlib++ - Win32 Debug" 
    5656 
    5757# PROP BASE Use_MFC 0 
    5858# PROP BASE Use_Debug_Libraries 1 
    59 # PROP BASE Output_Dir ".\output\pjlibpp-i386-win32-vc6-debug" 
    60 # PROP BASE Intermediate_Dir ".\output\pjlibpp-i386-win32-vc6-debug" 
     59# PROP BASE Output_Dir ".\output\pjlib++-i386-win32-vc6-debug" 
     60# PROP BASE Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-debug" 
    6161# PROP BASE Target_Dir "" 
    6262# PROP Use_MFC 0 
    6363# PROP Use_Debug_Libraries 1 
    64 # PROP Output_Dir ".\output\pjlibpp-i386-win32-vc6-debug" 
    65 # PROP Intermediate_Dir ".\output\pjlibpp-i386-win32-vc6-debug" 
     64# PROP Output_Dir ".\output\pjlib++-i386-win32-vc6-debug" 
     65# PROP Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-debug" 
    6666# PROP Target_Dir "" 
    6767# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 
    68 # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../src" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PJ_WIN32" /D "PJ_M_I386" /FD /GZ /c 
     68# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FD /GZ /c 
    6969# SUBTRACT CPP /YX 
    7070# ADD BASE RSC /l 0x409 /d "_DEBUG" 
     
    8181# Begin Target 
    8282 
    83 # Name "pjlibpp - Win32 Release" 
    84 # Name "pjlibpp - Win32 Debug" 
    85 # Begin Group "Source Files" 
    86  
    87 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 
    88 # Begin Source File 
    89  
    90 SOURCE="..\src\pj++\compiletest.cpp" 
    91 # End Source File 
    92 # Begin Source File 
    93  
    94 SOURCE="..\src\pj++\pj++.cpp" 
    95 # End Source File 
    96 # Begin Source File 
    97  
    98 SOURCE="..\src\pj++\proactor.cpp" 
    99 # End Source File 
    100 # End Group 
     83# Name "pjlib++ - Win32 Release" 
     84# Name "pjlib++ - Win32 Debug" 
    10185# Begin Group "Header Files" 
    10286 
     
    10488# Begin Source File 
    10589 
    106 SOURCE="..\src\pj++\hash.hpp" 
     90SOURCE="..\include\pj++\file.hpp" 
    10791# End Source File 
    10892# Begin Source File 
    10993 
    110 SOURCE="..\src\pj++\ioqueue.hpp" 
     94SOURCE="..\include\pj++\hash.hpp" 
    11195# End Source File 
    11296# Begin Source File 
    11397 
    114 SOURCE="..\src\pj++\list.hpp" 
     98SOURCE="..\include\pj++\list.hpp" 
    11599# End Source File 
    116100# Begin Source File 
    117101 
    118 SOURCE="..\src\pj++\os.hpp" 
     102SOURCE="..\include\pj++\lock.hpp" 
    119103# End Source File 
    120104# Begin Source File 
    121105 
    122 SOURCE="..\src\pjlib++.hpp" 
     106SOURCE="..\include\pj++\os.hpp" 
    123107# End Source File 
    124108# Begin Source File 
    125109 
    126 SOURCE="..\src\pj++\pool.hpp" 
     110SOURCE="..\include\pj++\pool.hpp" 
    127111# End Source File 
    128112# Begin Source File 
    129113 
    130 SOURCE="..\src\pj++\proactor.hpp" 
     114SOURCE="..\include\pj++\proactor.hpp" 
    131115# End Source File 
    132116# Begin Source File 
    133117 
    134 SOURCE="..\src\pj++\scanner.hpp" 
     118SOURCE="..\include\pj++\scanner.hpp" 
    135119# End Source File 
    136120# Begin Source File 
    137121 
    138 SOURCE="..\src\pj++\sock.hpp" 
     122SOURCE="..\include\pj++\sock.hpp" 
    139123# End Source File 
    140124# Begin Source File 
    141125 
    142 SOURCE="..\src\pj++\string.hpp" 
     126SOURCE="..\include\pj++\string.hpp" 
    143127# End Source File 
    144128# Begin Source File 
    145129 
    146 SOURCE="..\src\pj++\timer.hpp" 
     130SOURCE="..\include\pj++\timer.hpp" 
    147131# End Source File 
    148132# Begin Source File 
    149133 
    150 SOURCE="..\src\pj++\tree.hpp" 
     134SOURCE="..\include\pj++\tree.hpp" 
    151135# End Source File 
    152136# Begin Source File 
    153137 
    154 SOURCE="..\src\pj++\types.hpp" 
     138SOURCE="..\include\pj++\types.hpp" 
    155139# End Source File 
    156140# End Group 
  • pjproject/main/pjlib/build/pjlib.dsp

    r32 r36  
    235235 
    236236SOURCE=..\src\pj\ioqueue_winnt.c 
     237 
     238!IF  "$(CFG)" == "pjlib - Win32 Release" 
     239 
     240!ELSEIF  "$(CFG)" == "pjlib - Win32 Debug" 
     241 
     242!ENDIF  
     243 
    237244# End Source File 
    238245# Begin Source File 
  • pjproject/main/pjlib/build/pjlib.dsw

    r1 r36  
    44############################################################################### 
    55 
    6 Project: "pjlib"=".\pjlib.dsp" - Package Owner=<4> 
     6Project: "pjlib"=.\pjlib.dsp - Package Owner=<4> 
    77 
    88Package=<5> 
    99{{{ 
    10     begin source code control 
    11     "$/pjproject-0.3/pjlib/build", EJDAAAAA 
    12     . 
    13     end source code control 
    1410}}} 
    1511 
     
    2016############################################################################### 
    2117 
    22 Project: "pjlib_samples"=".\pjlib_samples.dsp" - Package Owner=<4> 
     18Project: "pjlib++"=".\pjlib++.dsp" - Package Owner=<4> 
    2319 
    2420Package=<5> 
    2521{{{ 
    26     begin source code control 
    27     "$/pjproject-0.3/pjlib/build", EJDAAAAA 
    28     . 
    29     end source code control 
     22}}} 
     23 
     24Package=<4> 
     25{{{ 
     26}}} 
     27 
     28############################################################################### 
     29 
     30Project: "pjlib_samples"=.\pjlib_samples.dsp - Package Owner=<4> 
     31 
     32Package=<5> 
     33{{{ 
    3034}}} 
    3135 
     
    3943############################################################################### 
    4044 
    41 Project: "pjlib_test"=".\pjlib_test.dsp" - Package Owner=<4> 
     45Project: "pjlib_test"=.\pjlib_test.dsp - Package Owner=<4> 
    4246 
    4347Package=<5> 
    4448{{{ 
    45     begin source code control 
    46     "$/pjproject-0.3/pjlib/build", EJDAAAAA 
    47     . 
    48     end source code control 
    4949}}} 
    5050 
     
    5858############################################################################### 
    5959 
    60 Project: "pjlibpp"=".\pjlibpp.dsp" - Package Owner=<4> 
     60Project: "pjlib++_test"=.\pjlib++-test.dsp - Package Owner=<4> 
    6161 
    6262Package=<5> 
    6363{{{ 
    64     begin source code control 
    65     "$/pjproject-0.3/pjlib/build", EJDAAAAA 
    66     . 
    67     end source code control 
    6864}}} 
    6965 
    7066Package=<4> 
    7167{{{ 
     68    Begin Project Dependency 
     69    Project_Dep_Name pjlib 
     70    End Project Dependency 
     71    Begin Project Dependency 
     72    Project_Dep_Name pjlib++ 
     73    End Project Dependency 
    7274}}} 
    7375 
     
    7880Package=<5> 
    7981{{{ 
    80     begin source code control 
    81     "$/pjproject-0.3/pjlib/build", EJDAAAAA 
    82     . 
    83     end source code control 
    8482}}} 
    8583 
  • pjproject/main/pjlib/include/pj++/hash.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_HASH_H__ 
     
    65 
    76#include <pj++/types.hpp> 
     7#include <pj++/pool.hpp> 
    88#include <pj/hash.h> 
    99 
    10 class PJ_Hash_Table 
     10// 
     11// Hash table. 
     12// 
     13class Pj_Hash_Table : public Pj_Object 
    1114{ 
    1215public: 
     16    // 
     17    // Hash table iterator. 
     18    // 
    1319    class iterator 
    1420    { 
    1521    public: 
    16         iterator() {} 
    17         explicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i) : ht_(h), it_(i) {} 
    18         iterator(const iterator &rhs) : ht_(rhs.ht_), it_(rhs.it_) {} 
    19         void operator++() { it_ = pj_hash_next(ht_, it_); } 
    20         bool operator==(const iterator &rhs) { return ht_ == rhs.ht_ && it_ == rhs.it_; } 
    21         iterator & operator=(const iterator &rhs) { ht_=rhs.ht_; it_=rhs.it_; return *this; } 
     22        iterator()  
     23        { 
     24        } 
     25        explicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i)  
     26        : ht_(h), it_(i)  
     27        { 
     28        } 
     29        iterator(const iterator &rhs)  
     30        : ht_(rhs.ht_), it_(rhs.it_)  
     31        { 
     32        } 
     33        void operator++()  
     34        {  
     35            it_ = pj_hash_next(ht_, it_);  
     36        } 
     37        bool operator==(const iterator &rhs)  
     38        {  
     39            return ht_ == rhs.ht_ && it_ == rhs.it_;  
     40        } 
     41        iterator & operator=(const iterator &rhs)  
     42        {  
     43            ht_=rhs.ht_; it_=rhs.it_;  
     44            return *this;  
     45        } 
    2246    private: 
    2347        pj_hash_table_t *ht_; 
     
    2549        pj_hash_iterator_t *it_; 
    2650 
    27         friend class PJ_Hash_Table; 
     51        friend class Pj_Hash_Table; 
    2852    }; 
    2953 
    30     static PJ_Hash_Table *create(PJ_Pool *pool, unsigned size) 
     54    // 
     55    // Construct hash table. 
     56    // 
     57    Pj_Hash_Table(Pj_Pool *pool, unsigned size) 
    3158    { 
    32         return (PJ_Hash_Table*) pj_hash_create(pool->pool_(), size); 
     59        table_ = pj_hash_create(pool->pool_(), size); 
    3360    } 
    3461 
    35     static pj_uint32_t calc(pj_uint32_t initial_hval, const void *key, unsigned keylen) 
     62    // 
     63    // Destroy hash table. 
     64    // 
     65    ~Pj_Hash_Table() 
     66    { 
     67    } 
     68 
     69    // 
     70    // Calculate hash value. 
     71    // 
     72    static pj_uint32_t calc( pj_uint32_t initial_hval,  
     73                             const void *key,  
     74                             unsigned keylen = PJ_HASH_KEY_STRING) 
    3675    { 
    3776        return pj_hash_calc(initial_hval, key, keylen); 
    3877    } 
    3978 
    40     pj_hash_table_t *hash_table_() 
     79    // 
     80    // Return pjlib compatible hash table object. 
     81    // 
     82    pj_hash_table_t *pj_hash_table_t_() 
    4183    { 
    42         return (pj_hash_table_t*)this; 
     84        return table_; 
    4385    } 
    4486 
    45     void *get(const void *key, unsigned keylen) 
     87    // 
     88    // Get the value associated with the specified key. 
     89    // 
     90    void *get(const void *key, unsigned keylen = PJ_HASH_KEY_STRING) 
    4691    { 
    47         return pj_hash_get(this->hash_table_(), key, keylen); 
     92        return pj_hash_get(table_, key, keylen); 
    4893    } 
    4994 
    50     void set(PJ_Pool *pool, const void *key, unsigned keylen, void *value) 
     95    // 
     96    // Associate a value with a key. 
     97    // Set the value to NULL to delete the key from the hash table. 
     98    // 
     99    void set(Pj_Pool *pool,  
     100             const void *key,  
     101             void *value, 
     102             unsigned keylen = PJ_HASH_KEY_STRING) 
    51103    { 
    52         pj_hash_set(pool->pool_(), this->hash_table_(), key, keylen, value); 
     104        pj_hash_set(pool->pool_(), table_, key, keylen, value); 
    53105    } 
    54106 
     107    // 
     108    // Get number of items in the hash table. 
     109    // 
    55110    unsigned count() 
    56111    { 
    57         return pj_hash_count(this->hash_table_()); 
     112        return pj_hash_count(table_); 
    58113    } 
    59114 
     115    // 
     116    // Iterate hash table. 
     117    // 
    60118    iterator begin() 
    61119    { 
    62         iterator it(this->hash_table_(), NULL); 
    63         it.it_ = pj_hash_first(this->hash_table_(), &it.it_val_); 
     120        iterator it(table_, NULL); 
     121        it.it_ = pj_hash_first(table_, &it.it_val_); 
    64122        return it; 
    65123    } 
    66124 
     125    // 
     126    // End of items. 
     127    // 
    67128    iterator end() 
    68129    { 
    69         return iterator(this->hash_table_(), NULL); 
     130        return iterator(table_, NULL); 
    70131    } 
     132 
     133private: 
     134    pj_hash_table_t *table_; 
    71135}; 
    72136 
     137 
    73138#endif  /* __PJPP_HASH_H__ */ 
     139 
  • pjproject/main/pjlib/include/pj++/list.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_LIST_H__ 
     
    65 
    76#include <pj/list.h> 
    8  
    9 template <typename T> 
    10 struct PJ_List_Node 
    11 { 
    12     PJ_DECL_LIST_MEMBER(T) 
    13 }; 
    14  
    15  
    16 template <class Node> 
    17 class PJ_List 
     7#include <pj++/pool.hpp> 
     8 
     9 
     10// 
     11// Linked-list. 
     12// 
     13// Note: 
     14//  List_Node must have public member next and prev. Normally 
     15//  it will be declared like: 
     16// 
     17//  struct my_node 
     18//  { 
     19//      PJ_DECL_LIST_MEMBER(struct my_node); 
     20//      .. 
     21//  }; 
     22// 
     23// 
     24template <class List_Node> 
     25class Pj_List : public Pj_Object 
    1826{ 
    1927public: 
    20     PJ_List() { pj_list_init(&root_); if (0) compiletest(); } 
    21     ~PJ_List() {} 
    22  
     28    // 
     29    // List const_iterator. 
     30    // 
    2331    class const_iterator 
    2432    { 
    2533    public: 
    26         const_iterator() : node_(NULL) {} 
    27         const_iterator(const Node *nd) : node_((Node*)nd) {} 
    28         const Node * operator *() { return node_; } 
    29         const Node * operator -> () { return node_; } 
    30         const_iterator operator++() { return const_iterator(node_->next); } 
    31         bool operator==(const const_iterator &rhs) { return node_ == rhs.node_; } 
    32         bool operator!=(const const_iterator &rhs) { return node_ != rhs.node_; } 
     34        const_iterator()  
     35            : node_(NULL)  
     36        {} 
     37        const_iterator(const List_Node *nd)  
     38            : node_((List_Node*)nd)  
     39        {} 
     40        const List_Node * operator *()  
     41        {  
     42            return node_;  
     43        } 
     44        const List_Node * operator -> ()  
     45        {  
     46            return node_;  
     47        } 
     48        const_iterator operator++()  
     49        {  
     50            return const_iterator(node_->next);  
     51        } 
     52        bool operator==(const const_iterator &rhs)  
     53        {  
     54            return node_ == rhs.node_;  
     55        } 
     56        bool operator!=(const const_iterator &rhs)  
     57        {  
     58            return node_ != rhs.node_;  
     59        } 
    3360 
    3461    protected: 
    35         Node *node_; 
     62        List_Node *node_; 
    3663    }; 
    3764 
     65    // 
     66    // List iterator. 
     67    // 
    3868    class iterator : public const_iterator 
    3969    { 
    4070    public: 
    41         iterator() {} 
    42         iterator(Node *nd) : const_iterator(nd) {} 
    43         Node * operator *() { return node_; } 
    44         Node * operator -> () { return node_; } 
    45         iterator operator++() { return iterator(node_->next); } 
    46         bool operator==(const iterator &rhs) { return node_ == rhs.node_; } 
    47         bool operator!=(const iterator &rhs) { return node_ != rhs.node_; } 
     71        iterator()  
     72        {} 
     73        iterator(List_Node *nd)  
     74            : const_iterator(nd)  
     75        {} 
     76        List_Node * operator *()  
     77        {  
     78            return node_;  
     79        } 
     80        List_Node * operator -> ()  
     81        {  
     82            return node_;  
     83        } 
     84        iterator operator++()  
     85        {  
     86            return iterator(node_->next);  
     87        } 
     88        bool operator==(const iterator &rhs)  
     89        {  
     90            return node_ == rhs.node_;  
     91        } 
     92        bool operator!=(const iterator &rhs)  
     93        {  
     94            return node_ != rhs.node_;  
     95        } 
    4896    }; 
    4997 
     98    // 
     99    // Default constructor. 
     100    // 
     101    Pj_List()  
     102    {  
     103        pj_list_init(&root_);  
     104        if (0) compiletest();  
     105    } 
     106 
     107    // 
     108    // Check if list is empty. 
     109    //  
    50110    bool empty() const 
    51111    { 
     
    53113    } 
    54114 
     115    // 
     116    // Get first element. 
     117    // 
    55118    iterator begin() 
    56119    { 
     
    58121    } 
    59122 
     123    // 
     124    // Get first element. 
     125    // 
    60126    const_iterator begin() const 
    61127    { 
     
    63129    } 
    64130 
     131    // 
     132    // Get end-of-element 
     133    // 
    65134    const_iterator end() const 
    66135    { 
    67         return const_iterator((Node*)&root_); 
    68     } 
    69  
     136        return const_iterator((List_Node*)&root_); 
     137    } 
     138 
     139    // 
     140    // Get end-of-element 
     141    // 
    70142    iterator end() 
    71143    { 
    72         return iterator((Node*)&root_); 
    73     } 
    74  
    75     void insert_before (iterator &pos, Node *node) 
     144        return iterator((List_Node*)&root_); 
     145    } 
     146 
     147    // 
     148    // Insert node. 
     149    // 
     150    void insert_before (iterator &pos, List_Node *node) 
    76151    { 
    77152        pj_list_insert_before( *pos, node ); 
    78153    } 
    79154 
    80     void insert_after(iterator &pos, Node *node) 
     155    // 
     156    // Insert node. 
     157    // 
     158    void insert_after(iterator &pos, List_Node *node) 
    81159    { 
    82160        pj_list_insert_after(*pos, node); 
    83161    } 
    84162 
    85     void merge_first(Node *list2) 
     163    // 
     164    // Merge list. 
     165    // 
     166    void merge_first(List_Node *list2) 
    86167    { 
    87168        pj_list_merge_first(&root_, list2); 
    88169    } 
    89170 
    90     void merge_last(PJ_List *list) 
     171    // 
     172    // Merge list. 
     173    // 
     174    void merge_last(Pj_List *list) 
    91175    { 
    92176        pj_list_merge_last(&root_, &list->root_); 
    93177    } 
    94178 
    95     void insert_nodes_before(iterator &pos, PJ_List *list2) 
     179    // 
     180    // Insert list. 
     181    // 
     182    void insert_nodes_before(iterator &pos, Pj_List *list2) 
    96183    { 
    97184        pj_list_insert_nodes_before(*pos, &list2->root_); 
    98185    } 
    99186 
    100     void insert_nodes_after(iterator &pos, PJ_List *list2) 
     187    // 
     188    // Insert list. 
     189    // 
     190    void insert_nodes_after(iterator &pos, Pj_List *list2) 
    101191    { 
    102192        pj_list_insert_nodes_after(*pos, &list2->root_); 
    103193    } 
    104194 
     195    // 
     196    // Erase an element. 
     197    // 
    105198    void erase(iterator &it) 
    106199    { 
     
    108201    } 
    109202 
    110     Node *front() 
     203    // 
     204    // Get first element. 
     205    // 
     206    List_Node *front() 
    111207    { 
    112208        return root_.next; 
    113209    } 
    114210 
    115     const Node *front() const 
     211    // 
     212    // Get first element. 
     213    // 
     214    const List_Node *front() const 
    116215    { 
    117216        return root_.next; 
    118217    } 
    119218 
     219    // 
     220    // Remove first element. 
     221    // 
    120222    void pop_front() 
    121223    { 
     
    123225    } 
    124226 
    125     Node *back() 
     227    // 
     228    // Get last element. 
     229    // 
     230    List_Node *back() 
    126231    { 
    127232        return root_.prev; 
    128233    } 
    129234 
    130     const Node *back() const 
     235    // 
     236    // Get last element. 
     237    // 
     238    const List_Node *back() const 
    131239    { 
    132240        return root_.prev; 
    133241    } 
    134242 
     243    // 
     244    // Remove last element. 
     245    // 
    135246    void pop_back() 
    136247    { 
     
    138249    } 
    139250 
    140     iterator find(Node *node) 
    141     { 
    142         Node *n = pj_list_find_node(&root_, node); 
     251    // 
     252    // Find a node. 
     253    // 
     254    iterator find(List_Node *node) 
     255    { 
     256        List_Node *n = pj_list_find_node(&root_, node); 
    143257        return n ? iterator(n) : end(); 
    144258    } 
    145259 
    146     const_iterator find(Node *node) const 
    147     { 
    148         Node *n = pj_list_find_node(&root_, node); 
     260    // 
     261    // Find a node. 
     262    // 
     263    const_iterator find(List_Node *node) const 
     264    { 
     265        List_Node *n = pj_list_find_node(&root_, node); 
    149266        return n ? const_iterator(n) : end(); 
    150267    } 
    151268 
    152     void push_back(Node *node) 
     269    // 
     270    // Insert a node in the back. 
     271    // 
     272    void push_back(List_Node *node) 
    153273    { 
    154274        pj_list_insert_after(root_.prev, node); 
    155275    } 
    156276 
    157     void push_front(Node *node) 
     277    // 
     278    // Insert a node in the front. 
     279    // 
     280    void push_front(List_Node *node) 
    158281    { 
    159282        pj_list_insert_before(root_.next, node); 
    160283    } 
    161284 
     285    // 
     286    // Remove all elements. 
     287    // 
    162288    void clear() 
    163289    { 
     
    169295    struct RootNode 
    170296    { 
    171         PJ_DECL_LIST_MEMBER(Node) 
     297        PJ_DECL_LIST_MEMBER(List_Node); 
    172298    } root_; 
    173299 
     
    175301    { 
    176302        // If you see error in this line,  
    177         // it's because Node is not derived from PJ_List_Node. 
    178         Node *n = (Node*)0; 
     303        // it's because List_Node is not derived from Pj_List_Node. 
     304        List_Node *n = (List_Node*)0; 
    179305        n = n->next; n = n->prev; 
    180306    } 
  • pjproject/main/pjlib/include/pj++/os.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_OS_H__ 
     
    98#include <pj++/pool.hpp> 
    109 
    11 class PJ_Thread 
     10class Pj_Thread; 
     11 
     12// 
     13// Thread API. 
     14// 
     15class Pj_Thread_API 
     16{ 
     17public: 
     18    // 
     19    // Create a thread. 
     20    // 
     21    static pj_status_t create( Pj_Pool *pool, pj_thread_t **thread, 
     22                               pj_thread_proc *proc, void *arg, 
     23                               unsigned flags = 0, 
     24                               const char *name = NULL, 
     25                               pj_size_t stack_size = 0 ) 
     26    { 
     27        return pj_thread_create(pool->pool_(), name, proc, arg, stack_size, 
     28                                flags, thread); 
     29    } 
     30 
     31    // 
     32    // Register a thread. 
     33    // 
     34    static pj_status_t register_this_thread( pj_thread_desc desc, 
     35                                             pj_thread_t **thread, 
     36                                             const char *name = NULL ) 
     37    { 
     38        return pj_thread_register( name, desc, thread ); 
     39    } 
     40 
     41    // 
     42    // Get current thread. 
     43    // Will return pj_thread_t (sorry folks, not Pj_Thread). 
     44    // 
     45    static pj_thread_t *this_thread() 
     46    { 
     47        return pj_thread_this(); 
     48    } 
     49 
     50    // 
     51    // Get thread name. 
     52    // 
     53    static const char *get_name(pj_thread_t *thread) 
     54    { 
     55        return pj_thread_get_name(thread); 
     56    } 
     57 
     58    // 
     59    // Resume thread. 
     60    // 
     61    static pj_status_t resume(pj_thread_t *thread) 
     62    { 
     63        return pj_thread_resume(thread); 
     64    } 
     65 
     66    // 
     67    // Sleep. 
     68    // 
     69    static pj_status_t sleep(unsigned msec) 
     70    { 
     71        return pj_thread_sleep(msec); 
     72    } 
     73 
     74    // 
     75    // Join the specified thread. 
     76    // 
     77    static pj_status_t join(pj_thread_t *thread) 
     78    { 
     79        return pj_thread_join(thread); 
     80    } 
     81 
     82    // 
     83    // Destroy thread 
     84    // 
     85    static pj_status_t destroy(pj_thread_t *thread) 
     86    { 
     87        return pj_thread_destroy(thread); 
     88    } 
     89}; 
     90 
     91 
     92 
     93// 
     94// Thread object. 
     95// 
     96// How to use: 
     97//  Derive a class from this class, then override main(). 
     98// 
     99class Pj_Thread : public Pj_Object 
    12100{ 
    13101public: 
     
    17105    }; 
    18106 
    19     static PJ_Thread *create( PJ_Pool *pool, const char *thread_name, 
    20                               pj_thread_proc *proc, void *arg, 
    21                               pj_size_t stack_size, void *stack_ptr,  
    22                               unsigned flags) 
    23     { 
    24         return (PJ_Thread*) pj_thread_create( pool->pool_(), thread_name, proc, arg, stack_size, stack_ptr, flags); 
    25     } 
    26  
    27     static PJ_Thread *register_current_thread(const char *name, pj_thread_desc desc) 
    28     { 
    29         return (PJ_Thread*) pj_thread_register(name, desc); 
    30     } 
    31  
    32     static PJ_Thread *get_current_thread() 
    33     { 
    34         return (PJ_Thread*) pj_thread_this(); 
    35     } 
    36  
    37     static pj_status_t sleep(unsigned msec) 
    38     { 
    39         return pj_thread_sleep(msec); 
    40     } 
    41  
    42     static pj_status_t usleep(unsigned usec) 
    43     { 
    44         return pj_thread_usleep(usec); 
    45     } 
    46  
     107    // 
     108    // Default constructor. 
     109    // 
     110    Pj_Thread() 
     111        : thread_(NULL) 
     112    { 
     113    } 
     114 
     115    // 
     116    // Destroy thread. 
     117    // 
     118    ~Pj_Thread() 
     119    { 
     120        destroy(); 
     121    } 
     122 
     123    // 
     124    // This is the main thread function. 
     125    // 
     126    virtual int main() = 0; 
     127 
     128    // 
     129    // Start a thread. 
     130    // 
     131    pj_status_t create( Pj_Pool *pool,  
     132                        unsigned flags = 0, 
     133                        const char *thread_name = NULL, 
     134                        pj_size_t stack_size = PJ_THREAD_DEFAULT_STACK_SIZE) 
     135    { 
     136        destroy(); 
     137        return Pj_Thread_API::create( pool, &thread_, &thread_proc, this, 
     138                                      flags, thread_name); 
     139    } 
     140 
     141    // 
     142    // Get pjlib compatible thread object. 
     143    // 
    47144    pj_thread_t *pj_thread_t_() 
    48145    { 
    49         return (pj_thread_t*)this; 
    50     } 
    51  
     146        return thread_; 
     147    } 
     148 
     149    // 
     150    // Get thread name. 
     151    // 
    52152    const char *get_name() 
    53153    { 
    54         return pj_thread_get_name( this->pj_thread_t_() ); 
    55     } 
    56  
     154        return Pj_Thread_API::get_name(thread_); 
     155    } 
     156 
     157    // 
     158    // Resume a suspended thread. 
     159    // 
    57160    pj_status_t resume() 
    58161    { 
    59         return pj_thread_resume( this->pj_thread_t_() ); 
    60     } 
    61  
     162        return Pj_Thread_API::resume(thread_); 
     163    } 
     164 
     165    // 
     166    // Join this thread. 
     167    // 
    62168    pj_status_t join() 
    63169    { 
    64         return pj_thread_join( this->pj_thread_t_() ); 
    65     } 
    66  
     170        return Pj_Thread_API::join(thread_); 
     171    } 
     172 
     173    // 
     174    // Destroy thread. 
     175    // 
    67176    pj_status_t destroy() 
    68177    { 
    69         return pj_thread_destroy( this->pj_thread_t_() ); 
    70     } 
    71 }; 
    72  
    73  
    74 class PJ_Thread_Local 
    75 { 
    76 public: 
    77     static PJ_Thread_Local *alloc() 
    78     { 
    79         long index = pj_thread_local_alloc(); 
    80         return index < 0 ? NULL : (PJ_Thread_Local*)index; 
    81     } 
    82     void free() 
    83     { 
    84         pj_thread_local_free( this->tls_() ); 
    85     } 
    86  
    87     long tls_() const 
    88     { 
    89         return (long)this; 
    90     } 
    91  
    92     void set(void *value) 
    93     { 
    94         pj_thread_local_set( this->tls_(), value ); 
    95     } 
    96  
    97     void *get() 
    98     { 
    99         return pj_thread_local_get( this->tls_() ); 
    100     } 
    101 }; 
    102  
    103  
    104 class PJ_Atomic 
    105 { 
    106 public: 
    107     static PJ_Atomic *create(PJ_Pool *pool, long initial) 
    108     { 
    109         return (PJ_Atomic*) pj_atomic_create(pool->pool_(), initial); 
    110     } 
    111  
     178        if (thread_) { 
     179            Pj_Thread_API::destroy(thread_); 
     180            thread_ = NULL; 
     181        } 
     182    } 
     183 
     184protected: 
     185    pj_thread_t *thread_; 
     186 
     187    static int PJ_THREAD_FUNC thread_proc(void *obj) 
     188    { 
     189        Pj_Thread *thread_class = (Pj_Thread*)obj; 
     190        return thread_class->main(); 
     191    } 
     192}; 
     193 
     194 
     195// 
     196// External Thread 
     197//  (threads that were started by external means, i.e. not  
     198//   with Pj_Thread::create). 
     199// 
     200// This class will normally be defined as local variable in 
     201// external thread's stack, normally inside thread's main proc. 
     202// But be aware that the handle will be destroyed on destructor! 
     203// 
     204class Pj_External_Thread : public Pj_Thread 
     205{ 
     206public: 
     207    Pj_External_Thread() 
     208    { 
     209    } 
     210 
     211    // 
     212    // Register external thread so that pjlib functions can work 
     213    // in that thread. 
     214    // 
     215    pj_status_t register_this_thread( const char *name=NULL ) 
     216    { 
     217        return Pj_Thread_API::register_this_thread(desc_, &thread_,name); 
     218    } 
     219 
     220private: 
     221    pj_thread_desc desc_; 
     222}; 
     223 
     224 
     225// 
     226// Thread specific data/thread local storage/TLS. 
     227// 
     228class Pj_Thread_Local_API 
     229{ 
     230public: 
     231    // 
     232    // Allocate thread local storage (TLS) index. 
     233    // 
     234    static pj_status_t alloc(long *index) 
     235    { 
     236        return pj_thread_local_alloc(index); 
     237    } 
     238 
     239    // 
     240    // Free TLS index. 
     241    // 
     242    static void free(long index) 
     243    { 
     244        pj_thread_local_free(index); 
     245    } 
     246 
     247    // 
     248    // Set thread specific data. 
     249    // 
     250    static pj_status_t set(long index, void *value) 
     251    { 
     252        return pj_thread_local_set(index, value); 
     253    } 
     254 
     255    // 
     256    // Get thread specific data. 
     257    // 
     258    static void *get(long index) 
     259    { 
     260        return pj_thread_local_get(index); 
     261    } 
     262 
     263}; 
     264 
     265// 
     266// Atomic variable 
     267// 
     268// How to use: 
     269//   Pj_Atomic_Var var(pool, 0); 
     270//   var.set(..); 
     271// 
     272class Pj_Atomic_Var : public Pj_Object 
     273{ 
     274public: 
     275    // 
     276    // Default constructor, initialize variable with NULL. 
     277    // 
     278    Pj_Atomic_Var() 
     279        : var_(NULL) 
     280    { 
     281    } 
     282 
     283    // 
     284    // Construct atomic variable. 
     285    // 
     286    Pj_Atomic_Var(Pj_Pool *pool, pj_atomic_value_t value) 
     287        : var_(NULL) 
     288    { 
     289        create(pool, value); 
     290    } 
     291 
     292    // 
     293    // Destructor. 
     294    // 
     295    ~Pj_Atomic_Var() 
     296    { 
     297        destroy(); 
     298    } 
     299 
     300    // 
     301    // Create atomic variable. 
     302    // 
     303    pj_status_t create( Pj_Pool *pool, pj_atomic_value_t value) 
     304    { 
     305        destroy(); 
     306        return pj_atomic_create(pool->pool_(), value, &var_); 
     307    } 
     308 
     309    // 
     310    // Destroy. 
     311    // 
     312    void destroy() 
     313    { 
     314        if (var_) { 
     315            pj_atomic_destroy(var_); 
     316            var_ = NULL; 
     317        } 
     318    } 
     319 
     320    // 
     321    // Get pjlib compatible atomic variable. 
     322    // 
    112323    pj_atomic_t *pj_atomic_t_() 
    113324    { 
    114         return (pj_atomic_t*)this; 
    115     } 
    116  
    117     pj_status_t destroy() 
    118     { 
    119         return pj_atomic_destroy( this->pj_atomic_t_() ); 
    120     } 
    121  
    122     long set(long val) 
    123     { 
    124         return pj_atomic_set( this->pj_atomic_t_(), val); 
    125     } 
    126  
    127     long get() 
    128     { 
    129         return pj_atomic_get( this->pj_atomic_t_() ); 
    130     } 
    131  
    132     long inc() 
    133     { 
    134         return pj_atomic_inc( this->pj_atomic_t_() ); 
    135     } 
    136  
    137     long dec() 
    138     { 
    139         return pj_atomic_dec( this->pj_atomic_t_() ); 
    140     } 
    141 }; 
    142  
    143  
    144 class PJ_Mutex 
    145 { 
    146 public: 
     325        return var_; 
     326    } 
     327 
     328    // 
     329    // Set the value. 
     330    // 
     331    void set(pj_atomic_value_t val) 
     332    { 
     333        pj_atomic_set(var_, val); 
     334    } 
     335 
     336    // 
     337    // Get the value. 
     338    // 
     339    pj_atomic_value_t get() 
     340    { 
     341        return pj_atomic_get(var_); 
     342    } 
     343 
     344    // 
     345    // Increment. 
     346    // 
     347    void inc() 
     348    { 
     349        pj_atomic_inc(var_); 
     350    } 
     351 
     352    // 
     353    // Increment and get the result. 
     354    // 
     355    pj_atomic_value_t inc_and_get() 
     356    { 
     357        return pj_atomic_inc_and_get(var_); 
     358    } 
     359 
     360    // 
     361    // Decrement. 
     362    // 
     363    void dec() 
     364    { 
     365        pj_atomic_dec(var_); 
     366    } 
     367 
     368    // 
     369    // Decrement and get the result. 
     370    // 
     371    pj_atomic_value_t dec_and_get() 
     372    { 
     373        return pj_atomic_dec_and_get(var_); 
     374    } 
     375 
     376    // 
     377    // Add the variable. 
     378    // 
     379    void add(pj_atomic_value_t value) 
     380    { 
     381        pj_atomic_add(var_, value); 
     382    } 
     383 
     384    // 
     385    // Add the variable and get the value. 
     386    // 
     387    pj_atomic_value_t add_and_get(pj_atomic_value_t value) 
     388    { 
     389        return pj_atomic_add_and_get(var_, value ); 
     390    } 
     391 
     392private: 
     393    pj_atomic_t *var_; 
     394}; 
     395 
     396 
     397// 
     398// Mutex 
     399// 
     400class Pj_Mutex : public Pj_Object 
     401{ 
     402public: 
     403    // 
     404    // Mutex type. 
     405    // 
    147406    enum Type 
    148407    { 
     
    152411    }; 
    153412 
    154     static PJ_Mutex *create( PJ_Pool *pool, const char *name, Type type) 
    155     { 
    156         return (PJ_Mutex*) pj_mutex_create( pool->pool_(), name, type); 
    157     } 
    158  
    159     pj_mutex_t *pj_mutex_() 
    160     { 
    161         return (pj_mutex_t*)this; 
    162     } 
    163  
    164     pj_status_t destroy() 
    165     { 
    166         return pj_mutex_destroy( this->pj_mutex_() ); 
    167     } 
    168  
    169     pj_status_t lock() 
    170     { 
    171         return pj_mutex_lock( this->pj_mutex_() ); 
    172     } 
    173  
    174     pj_status_t unlock() 
    175     { 
    176         return pj_mutex_unlock( this->pj_mutex_() ); 
    177     } 
    178  
    179     pj_status_t trylock() 
    180     { 
    181         return pj_mutex_trylock( this->pj_mutex_() ); 
    182     } 
    183  
    184 #if PJ_DEBUG 
    185     pj_status_t is_locked() 
    186     { 
    187         return pj_mutex_is_locked( this->pj_mutex_() ); 
    188     } 
    189 #endif 
    190 }; 
    191  
    192  
    193 class PJ_Semaphore 
    194 { 
    195 public: 
    196     static PJ_Semaphore *create( PJ_Pool *pool, const char *name, unsigned initial, unsigned max) 
    197     { 
    198         return (PJ_Semaphore*) pj_sem_create( pool->pool_(), name, initial, max); 
    199     } 
    200  
     413    // 
     414    // Default constructor will create default mutex. 
     415    // 
     416    explicit Pj_Mutex(Pj_Pool *pool, Type type = DEFAULT, 
     417                      const char *name = NULL) 
     418        : mutex_(NULL) 
     419    { 
     420        create(pool, type, name); 
     421    } 
     422 
     423    // 
     424    // Destructor. 
     425    // 
     426    ~Pj_Mutex() 
     427    { 
     428        destroy(); 
     429    } 
     430 
     431    // 
     432    // Create mutex. 
     433    // 
     434    pj_status_t create( Pj_Pool *pool, Type type, const char *name = NULL) 
     435    { 
     436        destroy(); 
     437        return pj_mutex_create( pool->pool_(), name, type, 
     438                                &mutex_ ); 
     439    } 
     440 
     441    // 
     442    // Create simple mutex. 
     443    // 
     444    pj_status_t create_simple( Pj_Pool *pool,const char *name = NULL) 
     445    { 
     446        return create(pool, SIMPLE, name); 
     447    } 
     448 
     449    // 
     450    // Create recursive mutex. 
     451    // 
     452    pj_status_t create_recursive( Pj_Pool *pool, const char *name = NULL ) 
     453    { 
     454        return create(pool, RECURSE, name); 
     455    } 
     456 
     457    // 
     458    // Get pjlib compatible mutex object. 
     459    // 
     460    pj_mutex_t *pj_mutex_t_() 
     461    { 
     462        return mutex_; 
     463    } 
     464 
     465    // 
     466    // Destroy mutex. 
     467    // 
     468    void destroy() 
     469    { 
     470        if (mutex_) { 
     471            pj_mutex_destroy(mutex_); 
     472            mutex_ = NULL; 
     473        } 
     474    } 
     475 
     476    // 
     477    // Lock mutex. 
     478    // 
     479    pj_status_t acquire() 
     480    { 
     481        return pj_mutex_lock(mutex_); 
     482    } 
     483 
     484    // 
     485    // Unlock mutex. 
     486    // 
     487    pj_status_t release() 
     488    { 
     489        return pj_mutex_unlock(mutex_); 
     490    } 
     491 
     492    // 
     493    // Try locking the mutex. 
     494    // 
     495    pj_status_t tryacquire() 
     496    { 
     497        return pj_mutex_trylock(mutex_); 
     498    } 
     499 
     500private: 
     501    pj_mutex_t *mutex_; 
     502}; 
     503 
     504 
     505// 
     506// Semaphore 
     507// 
     508class Pj_Semaphore : public Pj_Object 
     509{ 
     510public: 
     511    // 
     512    // Construct semaphore 
     513    // 
     514    Pj_Semaphore(Pj_Pool *pool, unsigned max, 
     515                 unsigned initial = 0, const char *name = NULL) 
     516    : sem_(NULL) 
     517    { 
     518    } 
     519 
     520    // 
     521    // Destructor. 
     522    // 
     523    ~Pj_Semaphore() 
     524    { 
     525        destroy(); 
     526    } 
     527 
     528    // 
     529    // Create semaphore 
     530    // 
     531    pj_status_t create( Pj_Pool *pool, unsigned max, 
     532                        unsigned initial = 0, const char *name = NULL ) 
     533    { 
     534        destroy(); 
     535        return pj_sem_create( pool->pool_(), name, initial, max, &sem_); 
     536    } 
     537 
     538    // 
     539    // Destroy semaphore. 
     540    // 
     541    void destroy() 
     542    { 
     543        if (sem_) { 
     544            pj_sem_destroy(sem_); 
     545            sem_ = NULL; 
     546        } 
     547    } 
     548 
     549    // 
     550    // Get pjlib compatible semaphore object. 
     551    // 
    201552    pj_sem_t *pj_sem_t_() 
    202553    { 
     
    204555    } 
    205556 
    206     pj_status_t destroy() 
    207     { 
    208         return pj_sem_destroy(this->pj_sem_t_()); 
    209     } 
    210  
     557    // 
     558    // Wait semaphore. 
     559    // 
    211560    pj_status_t wait() 
    212561    { 
     
    214563    } 
    215564 
    216     pj_status_t lock() 
     565    // 
     566    // Wait semaphore. 
     567    // 
     568    pj_status_t acquire() 
    217569    { 
    218570        return wait(); 
    219571    } 
    220572 
     573    // 
     574    // Try wait semaphore. 
     575    // 
    221576    pj_status_t trywait() 
    222577    { 
     
    224579    } 
    225580 
    226     pj_status_t trylock() 
     581    // 
     582    // Try wait semaphore. 
     583    // 
     584    pj_status_t tryacquire() 
    227585    { 
    228586        return trywait(); 
    229587    } 
    230588 
     589    // 
     590    // Post semaphore. 
     591    // 
    231592    pj_status_t post() 
    232593    { 
     
    234595    } 
    235596 
    236     pj_status_t unlock() 
     597    // 
     598    // Post semaphore. 
     599    // 
     600    pj_status_t release() 
    237601    { 
    238602        return post(); 
    239603    } 
    240 }; 
    241  
    242  
    243 class PJ_Event 
    244 { 
    245 public: 
    246     static PJ_Event *create( PJ_Pool *pool, const char *name, bool manual_reset, bool initial) 
    247     { 
    248         return (PJ_Event*) pj_event_create(pool->pool_(), name, manual_reset, initial); 
    249     } 
    250  
     604 
     605private: 
     606    pj_sem_t *sem_; 
     607}; 
     608 
     609 
     610// 
     611// Event object. 
     612// 
     613class Pj_Event 
     614{ 
     615public: 
     616    // 
     617    // Construct event object. 
     618    // 
     619    Pj_Event( Pj_Pool *pool, bool manual_reset = false, 
     620              bool initial = false, const char *name = NULL ) 
     621    : event_(NULL) 
     622    { 
     623        create(pool, manual_reset, initial, name); 
     624    } 
     625 
     626    // 
     627    // Destructor. 
     628    // 
     629    ~Pj_Event() 
     630    { 
     631        destroy(); 
     632    } 
     633 
     634    // 
     635    // Create event object. 
     636    // 
     637    pj_status_t create( Pj_Pool *pool, bool manual_reset = false,  
     638                        bool initial = false, const char *name = NULL) 
     639    { 
     640        destroy(); 
     641        return pj_event_create(pool->pool_(), name, manual_reset, initial, 
     642                               &event_); 
     643    } 
     644 
     645    // 
     646    // Get pjlib compatible event object. 
     647    // 
    251648    pj_event_t *pj_event_t_() 
    252649    { 
    253         return (pj_event_t*)this; 
    254     } 
    255  
    256     pj_status_t destroy() 
    257     { 
    258         return pj_event_destroy(this->pj_event_t_()); 
    259     } 
    260  
     650        return event_; 
     651    } 
     652 
     653    // 
     654    // Destroy event object. 
     655    // 
     656    void destroy() 
     657    { 
     658        if (event_) { 
     659            pj_event_destroy(event_); 
     660            event_ = NULL; 
     661        } 
     662    } 
     663 
     664    // 
     665    // Wait. 
     666    // 
    261667    pj_status_t wait() 
    262668    { 
    263         return pj_event_wait(this->pj_event_t_()); 
    264     } 
    265  
     669        return pj_event_wait(event_); 
     670    } 
     671 
     672    // 
     673    // Try wait. 
     674    // 
    266675    pj_status_t trywait() 
    267676    { 
    268         return pj_event_trywait(this->pj_event_t_()); 
    269     } 
    270  
     677        return pj_event_trywait(event_); 
     678    } 
     679 
     680    // 
     681    // Set event state to signalled. 
     682    // 
    271683    pj_status_t set() 
    272684    { 
     
    274686    } 
    275687 
     688    // 
     689    // Release one waiting thread. 
     690    // 
    276691    pj_status_t pulse() 
    277692    { 
     
    279694    } 
    280695 
     696    // 
     697    // Set a non-signalled. 
     698    // 
    281699    pj_status_t reset() 
    282700    { 
    283701        return pj_event_reset(this->pj_event_t_()); 
    284702    } 
    285 }; 
    286  
    287 class PJ_OS 
    288 { 
    289 public: 
    290     static pj_status_t gettimeofday( PJ_Time_Val *tv ) 
     703 
     704private: 
     705    pj_event_t *event_; 
     706}; 
     707 
     708// 
     709// OS abstraction. 
     710// 
     711class Pj_OS_API 
     712{ 
     713public: 
     714    // 
     715    // Get current time. 
     716    // 
     717    static pj_status_t gettimeofday( Pj_Time_Val *tv ) 
    291718    { 
    292719        return pj_gettimeofday(tv); 
    293720    } 
    294721 
    295     static pj_status_t time_decode( const PJ_Time_Val *tv, pj_parsed_time *pt ) 
     722    // 
     723    // Parse to time of day. 
     724    // 
     725    static pj_status_t time_decode( const Pj_Time_Val *tv,  
     726                                    pj_parsed_time *pt ) 
    296727    { 
    297728        return pj_time_decode(tv, pt); 
    298729    } 
    299730 
    300     static pj_status_t time_encode(const pj_parsed_time *pt, PJ_Time_Val *tv) 
     731    // 
     732    // Parse from time of day. 
     733    // 
     734    static pj_status_t time_encode( const pj_parsed_time *pt,  
     735                                    Pj_Time_Val *tv) 
    301736    { 
    302737        return pj_time_encode(pt, tv); 
    303738    } 
    304739 
    305     static pj_status_t time_local_to_gmt( PJ_Time_Val *tv ) 
     740    // 
     741    // Convert to GMT. 
     742    // 
     743    static pj_status_t time_local_to_gmt( Pj_Time_Val *tv ) 
    306744    { 
    307745        return pj_time_local_to_gmt( tv ); 
    308746    } 
    309747 
    310     static pj_status_t time_gmt_to_local( PJ_Time_Val *tv)  
     748    // 
     749    // Convert time to local. 
     750    // 
     751    static pj_status_t time_gmt_to_local( Pj_Time_Val *tv)  
    311752    { 
    312753        return pj_time_gmt_to_local( tv ); 
     
    314755}; 
    315756 
    316  
    317 inline pj_status_t PJ_Time_Val::gettimeofday() 
    318 { 
    319     return PJ_OS::gettimeofday(this); 
     757// 
     758// Timeval inlines. 
     759// 
     760inline pj_status_t Pj_Time_Val::gettimeofday() 
     761{ 
     762    return Pj_OS_API::gettimeofday(this); 
    320763} 
    321764 
    322 inline pj_parsed_time PJ_Time_Val::decode() 
     765inline pj_parsed_time Pj_Time_Val::decode() 
    323766{ 
    324767    pj_parsed_time pt; 
    325     PJ_OS::time_decode(this, &pt); 
     768    Pj_OS_API::time_decode(this, &pt); 
    326769    return pt; 
    327770} 
    328771 
    329 inline pj_status_t PJ_Time_Val::encode(const pj_parsed_time *pt) 
    330 { 
    331     return PJ_OS::time_encode(pt, this); 
     772inline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt) 
     773{ 
     774    return Pj_OS_API::time_encode(pt, this); 
    332775} 
    333776 
    334 inline pj_status_t PJ_Time_Val::to_gmt() 
    335 { 
    336     return PJ_OS::time_local_to_gmt(this); 
     777inline pj_status_t Pj_Time_Val::to_gmt() 
     778{ 
     779    return Pj_OS_API::time_local_to_gmt(this); 
    337780} 
    338781 
    339 inline pj_status_t PJ_Time_Val::to_local() 
    340 { 
    341     return PJ_OS::time_gmt_to_local(this); 
     782inline pj_status_t Pj_Time_Val::to_local() 
     783{ 
     784    return Pj_OS_API::time_gmt_to_local(this); 
    342785} 
    343786 
  • pjproject/main/pjlib/include/pj++/pool.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_POOL_H__ 
     
    76#include <pj/pool.h> 
    87 
    9 class PJ_Pool 
     8class Pj_Pool; 
     9class Pj_Caching_Pool; 
     10 
     11// 
     12// Base class for all Pjlib objects 
     13// 
     14class Pj_Object 
    1015{ 
    1116public: 
     17    void *operator new(unsigned int class_size, Pj_Pool *pool); 
     18    void operator delete(void*); 
     19    void operator delete(void*, Pj_Pool*); 
     20 
     21    // 
     22    // Inline implementations at the end of this file. 
     23    // 
     24 
     25private: 
     26    // Can not use normal new operator; must use pool. 
     27    // e.g.: 
     28    //   obj = new(pool) Pj_The_Object(pool, ...); 
     29    // 
     30    void *operator new(unsigned int) 
     31    {} 
     32}; 
     33 
     34 
     35// 
     36// Pool. 
     37// 
     38class Pj_Pool : public Pj_Object 
     39{ 
     40public: 
     41    // 
     42    // Default constructor, initializes internal pool to NULL. 
     43    // Application must call attach() some time later. 
     44    // 
     45    Pj_Pool() 
     46        : p_(NULL) 
     47    { 
     48    } 
     49 
     50    // 
     51    // Create pool. 
     52    // 
     53    Pj_Pool(Pj_Caching_Pool &caching_pool, 
     54            pj_size_t initial_size,  
     55            pj_size_t increment_size,  
     56            const char *name = NULL,  
     57            pj_pool_callback *callback = NULL); 
     58 
     59    // 
     60    // Construct from existing pool. 
     61    // 
     62    explicit Pj_Pool(pj_pool_t *pool) 
     63        : p_(pool) 
     64    { 
     65    } 
     66 
     67    // 
     68    // Attach existing pool. 
     69    // 
     70    void attach(pj_pool_t *pool) 
     71    { 
     72        p_ = pool; 
     73    } 
     74 
     75    // 
     76    // Destructor. 
     77    // 
     78    // Release pool back to factory. Remember: if you delete pool, then  
     79    // make sure that all objects that have been allocated from this pool 
     80    // have been properly destroyed. 
     81    // 
     82    // This is where C++ is trickier than plain C!! 
     83    // 
     84    ~Pj_Pool() 
     85    { 
     86        if (p_) 
     87            pj_pool_release(p_); 
     88    } 
     89 
     90    // 
     91    // Get name. 
     92    // 
    1293    const char *getobjname() const 
    1394    { 
    14         return pj_pool_getobjname(this->pool_()); 
    15     } 
    16  
     95        return pj_pool_getobjname(p_); 
     96    } 
     97 
     98    // 
     99    // Get pjlib compatible pool object. 
     100    // 
    17101    pj_pool_t *pool_() 
    18102    { 
    19         return (pj_pool_t*)this; 
    20     } 
    21  
     103        return p_; 
     104    } 
     105 
     106    // 
     107    // Get pjlib compatible pool object. 
     108    // 
    22109    const pj_pool_t *pool_() const 
    23110    { 
    24         return (const pj_pool_t*)this; 
    25     } 
    26  
    27     void release() 
    28     { 
    29         pj_pool_release(this->pool_()); 
    30     } 
    31  
     111        return p_; 
     112    } 
     113 
     114    // 
     115    // Get pjlib compatible pool object. 
     116    // 
     117    pj_pool_t *pj_pool_t_() 
     118    { 
     119        return p_; 
     120    } 
     121 
     122    // 
     123    // Reset pool. 
     124    // 
    32125    void reset() 
    33126    { 
    34         pj_pool_reset(this->pool_()); 
    35     } 
    36  
     127        pj_pool_reset(p_); 
     128    } 
     129 
     130    // 
     131    // Get current capacity. 
     132    // 
    37133    pj_size_t get_capacity() 
    38134    { 
    39         pj_pool_get_capacity(this->pool_()); 
    40     } 
    41  
     135        pj_pool_get_capacity(p_); 
     136    } 
     137 
     138    // 
     139    // Get current total bytes allocated from the pool. 
     140    // 
    42141    pj_size_t get_used_size() 
    43142    { 
    44         pj_pool_get_used_size(this->pool_()); 
    45     } 
    46  
     143        pj_pool_get_used_size(p_); 
     144    } 
     145 
     146    // 
     147    // Allocate. 
     148    // 
    47149    void *alloc(pj_size_t size) 
    48150    { 
    49         return pj_pool_alloc(this->pool_(), size); 
    50     } 
    51  
     151        return pj_pool_alloc(p_, size); 
     152    } 
     153 
     154    // 
     155    // Allocate elements and zero fill the memory. 
     156    // 
    52157    void *calloc(pj_size_t count, pj_size_t elem) 
    53158    { 
    54         return pj_pool_calloc(this->pool_(), count, elem); 
    55     } 
     159        return pj_pool_calloc(p_, count, elem); 
     160    } 
     161 
     162    // 
     163    // Allocate and zero fill memory. 
     164    // 
     165    void *zalloc(pj_size_t size) 
     166    { 
     167        return pj_pool_zalloc(p_, size); 
     168    } 
     169 
     170private: 
     171    pj_pool_t *p_; 
    56172}; 
    57173 
    58 class PJ_Caching_Pool 
     174 
     175// 
     176// Caching pool. 
     177// 
     178class Pj_Caching_Pool 
    59179{ 
    60180public: 
    61     void init(pj_size_t max_capacity, 
    62               const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy) 
    63     { 
    64         pj_caching_pool_init(&cp_, pol, max_capacity); 
    65     } 
    66  
    67     void destroy() 
     181    // 
     182    // Construct caching pool. 
     183    // 
     184    Pj_Caching_Pool( pj_size_t cache_capacity = 0, 
     185                     const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy) 
     186    { 
     187        pj_caching_pool_init(&cp_, pol, cache_capacity); 
     188    } 
     189 
     190    // 
     191    // Destroy caching pool. 
     192    // 
     193    ~Pj_Caching_Pool() 
    68194    { 
    69195        pj_caching_pool_destroy(&cp_); 
    70196    } 
    71197 
    72     PJ_Pool *create_pool(const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback) 
    73     { 
    74         return (PJ_Pool*) (*cp_.factory.create_pool)(&cp_.factory, name, initial_size, increment_size, callback); 
    75     } 
    76  
    77     void release_pool( PJ_Pool *pool ) 
    78     { 
    79         pj_pool_release(pool->pool_()); 
     198    // 
     199    // Create pool. 
     200    // 
     201    pj_pool_t *create_pool( pj_size_t initial_size,  
     202                            pj_size_t increment_size,  
     203                            const char *name = NULL,  
     204                            pj_pool_callback *callback = NULL) 
     205    { 
     206        return (pj_pool_t*)(*cp_.factory.create_pool)(&cp_.factory, name,  
     207                                                     initial_size,  
     208                                                     increment_size,  
     209                                                     callback); 
    80210    } 
    81211 
     
    84214}; 
    85215 
     216// 
     217// Inlines for Pj_Object 
     218// 
     219inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool *pool) 
     220{ 
     221    return pool->alloc(class_size); 
     222} 
     223inline void Pj_Object::operator delete(void *ptr) 
     224{ 
     225} 
     226inline void Pj_Object::operator delete(void *ptr, Pj_Pool*) 
     227{ 
     228} 
     229 
     230// 
     231// Inlines for Pj_Pool 
     232// 
     233inline Pj_Pool::Pj_Pool( Pj_Caching_Pool &caching_pool, 
     234                         pj_size_t initial_size,  
     235                         pj_size_t increment_size,  
     236                         const char *name,  
     237                         pj_pool_callback *callback) 
     238{ 
     239    p_ = caching_pool.create_pool(initial_size, increment_size, name, 
     240                                  callback); 
     241} 
     242 
     243 
    86244#endif  /* __PJPP_POOL_H__ */ 
  • pjproject/main/pjlib/include/pj++/proactor.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    4 #ifndef __PJPP_EVENT_HANDLER_H__ 
    5 #define __PJPP_EVENT_HANDLER_H__ 
     3#ifndef __PJPP_PROACTOR_H__ 
     4#define __PJPP_PROACTOR_H__ 
    65 
    76#include <pj/ioqueue.h> 
     
    98#include <pj++/sock.hpp> 
    109#include <pj++/timer.hpp> 
    11  
    12 class PJ_Proactor; 
    13  
    14  
    15 class PJ_Event_Handler 
     10#include <pj/errno.h> 
     11 
     12class Pj_Proactor; 
     13class Pj_Event_Handler; 
     14 
     15 
     16////////////////////////////////////////////////////////////////////////////// 
     17// Asynchronous operation key. 
     18// 
     19// Applications may inheric this class to put their application 
     20// specific data. 
     21// 
     22class Pj_Async_Op : public pj_ioqueue_op_key_t 
    1623{ 
    17     friend class PJ_Proactor; 
    1824public: 
    19     PJ_Event_Handler(); 
    20     virtual ~PJ_Event_Handler(); 
    21  
    22     virtual pj_oshandle_t get_handle() = 0; 
    23  
    24     bool read(void *buf, pj_size_t len); 
    25     bool recvfrom(void *buf, pj_size_t len, PJ_INET_Addr *addr); 
    26     bool write(const void *data, pj_size_t len); 
    27     bool sendto(const void *data, pj_size_t len, const PJ_INET_Addr &addr); 
     25    // 
     26    // Constructor. 
     27    // 
     28    explicit Pj_Async_Op(Pj_Event_Handler *handler) 
     29        : handler_(handler) 
     30    { 
     31        pj_memset(this, 0, sizeof(pj_ioqueue_op_key_t)); 
     32    } 
     33 
     34    // 
     35    // Check whether operation is still pending for this key. 
     36    // 
     37    bool is_pending(); 
     38 
     39    // 
     40    // Cancel the operation. 
     41    // 
     42    bool cancel(pj_ssize_t bytes_status=-PJ_ECANCELLED); 
     43 
     44protected: 
     45    Pj_Event_Handler *handler_; 
     46}; 
     47 
     48 
     49////////////////////////////////////////////////////////////////////////////// 
     50// Event handler. 
     51// 
     52// Applications should inherit this class to receive various event 
     53// notifications. 
     54// 
     55// Applications should implement get_socket_handle(). 
     56// 
     57class Pj_Event_Handler : public Pj_Object 
     58{ 
     59    friend class Pj_Proactor; 
     60public: 
     61    // 
     62    // Default constructor. 
     63    // 
     64    Pj_Event_Handler() 
     65        : key_(NULL) 
     66    { 
     67        pj_memset(&timer_, 0, sizeof(timer_)); 
     68        timer_.user_data = this; 
     69        timer_.cb = &timer_callback; 
     70    } 
     71     
     72    // 
     73    // Destroy. 
     74    // 
     75    virtual ~Pj_Event_Handler() 
     76    { 
     77        unregister(); 
     78    } 
     79 
     80    // 
     81    // Unregister this handler from the ioqueue. 
     82    // 
     83    void unregister() 
     84    { 
     85        if (key_) { 
     86            pj_ioqueue_unregister(key_); 
     87            key_ = NULL; 
     88        } 
     89    } 
     90 
     91    // 
     92    // Get socket handle associated with this. 
     93    // 
     94    virtual pj_sock_t get_socket_handle() 
     95    { 
     96        return PJ_INVALID_SOCKET; 
     97    } 
     98 
     99    // 
     100    // Receive data. 
     101    // 
     102    pj_status_t recv( Pj_Async_Op *op_key,  
     103                      void *buf, pj_ssize_t *len,  
     104                      unsigned flags) 
     105    { 
     106        return pj_ioqueue_recv( key_, op_key, 
     107                                buf, len, flags); 
     108    } 
     109 
     110    // 
     111    // Recvfrom() 
     112    // 
     113    pj_status_t recvfrom( Pj_Async_Op *op_key,  
     114                          void *buf, pj_ssize_t *len, unsigned flags, 
     115                          Pj_Inet_Addr *addr) 
     116    { 
     117        addr->addrlen_ = sizeof(Pj_Inet_Addr); 
     118        return pj_ioqueue_recvfrom( key_, op_key, buf, len, flags, 
     119                                    addr, &addr->addrlen_ ); 
     120    } 
     121 
     122    // 
     123    // send() 
     124    // 
     125    pj_status_t send( Pj_Async_Op *op_key,  
     126                      const void *data, pj_ssize_t *len,  
     127                      unsigned flags) 
     128    { 
     129        return pj_ioqueue_send( key_, op_key, data, len, flags); 
     130    } 
     131 
     132    // 
     133    // sendto() 
     134    // 
     135    pj_status_t sendto( Pj_Async_Op *op_key, 
     136                        const void *data, pj_ssize_t *len, unsigned flags, 
     137                        const Pj_Inet_Addr &addr) 
     138    { 
     139        return pj_ioqueue_sendto(key_, op_key, data, len, flags, 
     140                                 &addr, sizeof(addr)); 
     141    } 
     142 
    28143#if PJ_HAS_TCP 
    29     bool connect(const PJ_INET_Addr &addr); 
    30     bool accept(PJ_Socket *sock, PJ_INET_Addr *local=NULL, PJ_INET_Addr *remote=NULL); 
     144    // 
     145    // connect() 
     146    // 
     147    pj_status_t connect(const Pj_Inet_Addr &addr) 
     148    { 
     149        return pj_ioqueue_connect(key_, &addr, sizeof(addr)); 
     150    } 
     151 
     152    // 
     153    // accept. 
     154    // 
     155    pj_status_t accept( Pj_Async_Op *op_key, 
     156                        Pj_Socket *sock,  
     157                        Pj_Inet_Addr *local = NULL,  
     158                        Pj_Inet_Addr *remote = NULL) 
     159    { 
     160        int *addrlen = local ? &local->addrlen_ : NULL; 
     161        return pj_ioqueue_accept( key_, op_key, &sock->sock_, 
     162                                  local, remote, addrlen ); 
     163    } 
     164 
    31165#endif 
    32166 
    33167protected: 
    34     // 
     168    ////////////////// 
    35169    // Overridables 
    36     // 
    37     virtual void on_timeout(int data) {} 
    38     virtual void on_read_complete(pj_ssize_t bytes_read) {} 
    39     virtual void on_write_complete(pj_ssize_t bytes_sent) {} 
     170    ////////////////// 
     171 
     172    // 
     173    // Timeout callback. 
     174    // 
     175    virtual void on_timeout(int data)  
     176    { 
     177    } 
     178 
     179    // 
     180    // On read complete callback. 
     181    // 
     182    virtual void on_read_complete( Pj_Async_Op *op_key, 
     183                                   pj_ssize_t bytes_read)  
     184    { 
     185    } 
     186 
     187    // 
     188    // On write complete callback. 
     189    // 
     190    virtual void on_write_complete( Pj_Async_Op *op_key,  
     191                                    pj_ssize_t bytes_sent)  
     192    { 
     193    } 
     194 
    40195#if PJ_HAS_TCP 
    41     virtual void on_connect_complete(int status) {} 
    42     virtual void on_accept_complete(int status) {} 
     196    // 
     197    // On connect complete callback. 
     198    // 
     199    virtual void on_connect_complete(pj_status_t status)  
     200    { 
     201    } 
     202 
     203    // 
     204    // On new connection callback. 
     205    // 
     206    virtual void on_accept_complete( Pj_Async_Op *op_key, 
     207                                     pj_sock_t new_sock, 
     208                                     pj_status_t status)  
     209    { 
     210    } 
     211 
    43212#endif 
    44213 
     214 
    45215private: 
    46     PJ_Proactor      *proactor_; 
    47216    pj_ioqueue_key_t *key_; 
    48217    pj_timer_entry    timer_; 
    49     int               tmp_recvfrom_addr_len; 
    50  
    51 public: 
    52     // Internal IO Queue/timer callback. 
    53     static void timer_callback( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry); 
    54     static void read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read); 
    55     static void write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent); 
    56     static void accept_complete_cb(pj_ioqueue_key_t *key, int status); 
    57     static void connect_complete_cb(pj_ioqueue_key_t *key, int status); 
     218 
     219    friend class Pj_Proactor; 
     220    friend class Pj_Async_Op; 
     221 
     222    // 
     223    // Static timer callback. 
     224    // 
     225    static void timer_callback( pj_timer_heap_t *timer_heap,  
     226                                struct pj_timer_entry *entry) 
     227    { 
     228        Pj_Event_Handler *handler =  
     229            (Pj_Event_Handler*) entry->user_data; 
     230 
     231        handler->on_timeout(entry->id); 
     232    } 
    58233}; 
    59234 
    60 class PJ_Proactor 
     235inline bool Pj_Async_Op::is_pending() 
     236{ 
     237    return pj_ioqueue_is_pending(handler_->key_, this) != 0; 
     238} 
     239 
     240inline bool Pj_Async_Op::cancel(pj_ssize_t bytes_status) 
     241{ 
     242    return pj_ioqueue_post_completion(handler_->key_, this,  
     243                                      bytes_status) == PJ_SUCCESS; 
     244} 
     245 
     246////////////////////////////////////////////////////////////////////////////// 
     247// Proactor 
     248// 
     249class Pj_Proactor : public Pj_Object 
    61250{ 
    62251public: 
    63     static PJ_Proactor *create(PJ_Pool *pool, pj_size_t max_fd,  
    64                                pj_size_t timer_entry_count, unsigned timer_flags=0); 
    65  
    66     void destroy(); 
    67  
    68     bool register_handler(PJ_Pool *pool, PJ_Event_Handler *handler); 
    69     void unregister_handler(PJ_Event_Handler *handler); 
    70  
    71     static bool schedule_timer( pj_timer_heap_t *timer, PJ_Event_Handler *handler, 
    72                                 const PJ_Time_Val &delay, int id=-1); 
    73     bool schedule_timer(PJ_Event_Handler *handler, const PJ_Time_Val &delay, int id=-1); 
    74     bool cancel_timer(PJ_Event_Handler *handler); 
    75  
    76     bool handle_events(PJ_Time_Val *timeout); 
    77  
    78     pj_ioqueue_t *get_io_queue(); 
    79     pj_timer_heap_t *get_timer_heap(); 
     252    // 
     253    // Default constructor, initializes to NULL. 
     254    // 
     255    Pj_Proactor() 
     256        : ioq_(NULL), th_(NULL) 
     257    { 
     258        cb_.on_read_complete    = &read_complete_cb; 
     259        cb_.on_write_complete   = &write_complete_cb; 
     260        cb_.on_accept_complete  = &accept_complete_cb; 
     261        cb_.on_connect_complete = &connect_complete_cb; 
     262    } 
     263 
     264    // 
     265    // Construct proactor. 
     266    // 
     267    Pj_Proactor( Pj_Pool *pool, pj_size_t max_fd, 
     268                 pj_size_t max_timer_entries ) 
     269    : ioq_(NULL), th_(NULL) 
     270    { 
     271        cb_.on_read_complete    = &read_complete_cb; 
     272        cb_.on_write_complete   = &write_complete_cb; 
     273        cb_.on_accept_complete  = &accept_complete_cb; 
     274        cb_.on_connect_complete = &connect_complete_cb; 
     275    } 
     276 
     277    // 
     278    // Destructor. 
     279    // 
     280    ~Pj_Proactor() 
     281    { 
     282        destroy(); 
     283    } 
     284 
     285    // 
     286    // Create proactor. 
     287    // 
     288    pj_status_t create( Pj_Pool *pool, pj_size_t max_fd,  
     289                        pj_size_t timer_entry_count) 
     290    { 
     291        pj_status_t status; 
     292 
     293        destroy(); 
     294 
     295        status = pj_ioqueue_create(pool->pool_(), max_fd, &ioq_); 
     296        if (status != PJ_SUCCESS)  
     297            return status; 
     298         
     299        status = pj_timer_heap_create(pool->pool_(),  
     300                                      timer_entry_count, &th_); 
     301        if (status != PJ_SUCCESS) { 
     302            pj_ioqueue_destroy(ioq_); 
     303            ioq_ = NULL; 
     304            return NULL; 
     305        } 
     306         
     307        status; 
     308    } 
     309 
     310    // 
     311    // Destroy proactor. 
     312    // 
     313    void destroy() 
     314    { 
     315        if (ioq_) { 
     316            pj_ioqueue_destroy(ioq_); 
     317            ioq_ = NULL; 
     318        } 
     319        if (th_) { 
     320            pj_timer_heap_destroy(th_); 
     321            th_ = NULL; 
     322        } 
     323    } 
     324 
     325    // 
     326    // Register handler. 
     327    // This will call handler->get_socket_handle() 
     328    // 
     329    pj_status_t register_socket_handler(Pj_Pool *pool,  
     330                                        Pj_Event_Handler *handler) 
     331    { 
     332        return   pj_ioqueue_register_sock( pool->pool_(), ioq_, 
     333                                           handler->get_socket_handle(), 
     334                                           handler, &cb_, &handler->key_ ); 
     335    } 
     336 
     337    // 
     338    // Unregister handler. 
     339    // 
     340    static void unregister_handler(Pj_Event_Handler *handler) 
     341    { 
     342        if (handler->key_) { 
     343            pj_ioqueue_unregister( handler->key_ ); 
     344            handler->key_ = NULL; 
     345        } 
     346    } 
     347 
     348    // 
     349    // Scheduler timer. 
     350    // 
     351    bool schedule_timer( Pj_Event_Handler *handler,  
     352                         const Pj_Time_Val &delay,  
     353                         int id=-1) 
     354    { 
     355        return schedule_timer(th_, handler, delay, id); 
     356    } 
     357 
     358    // 
     359    // Cancel timer. 
     360    // 
     361    bool cancel_timer(Pj_Event_Handler *handler) 
     362    { 
     363        return pj_timer_heap_cancel(th_, &handler->timer_) == 1; 
     364    } 
     365 
     366    // 
     367    // Handle events. 
     368    // 
     369    int handle_events(Pj_Time_Val *max_timeout) 
     370    { 
     371        Pj_Time_Val timeout(0, 0); 
     372        int timer_count; 
     373 
     374        timer_count = pj_timer_heap_poll( th_, &timeout ); 
     375 
     376        if (timeout.get_sec() < 0)  
     377            timeout.sec = PJ_MAXINT32; 
     378 
     379        /* If caller specifies maximum time to wait, then compare the value  
     380         * with the timeout to wait from timer, and use the minimum value. 
     381         */ 
     382        if (max_timeout && timeout >= *max_timeout) { 
     383            timeout = *max_timeout; 
     384        } 
     385 
     386        /* Poll events in ioqueue. */ 
     387        int ioqueue_count; 
     388 
     389        ioqueue_count = pj_ioqueue_poll(ioq_, &timeout); 
     390        if (ioqueue_count < 0) 
     391            return ioqueue_count; 
     392 
     393        return ioqueue_count + timer_count; 
     394    } 
     395 
     396    // 
     397    // Get the internal ioqueue object. 
     398    // 
     399    pj_ioqueue_t *get_io_queue() 
     400    { 
     401        return ioq_; 
     402    } 
     403 
     404    // 
     405    // Get the internal timer heap object. 
     406    // 
     407    pj_timer_heap_t *get_timer_heap() 
     408    { 
     409        return th_; 
     410    } 
    80411 
    81412private: 
    82413    pj_ioqueue_t *ioq_; 
    83414    pj_timer_heap_t *th_; 
    84  
    85     PJ_Proactor() {} 
     415    pj_ioqueue_callback cb_; 
     416 
     417    static bool schedule_timer( pj_timer_heap_t *timer,  
     418                                Pj_Event_Handler *handler, 
     419                                const Pj_Time_Val &delay,  
     420                                int id=-1) 
     421    { 
     422        handler->timer_.id = id; 
     423        return pj_timer_heap_schedule(timer, &handler->timer_, &delay) == 0; 
     424    } 
     425 
     426 
     427    // 
     428    // Static read completion callback. 
     429    // 
     430    static void read_complete_cb( pj_ioqueue_key_t *key,  
     431                                  pj_ioqueue_op_key_t *op_key,  
     432                                  pj_ssize_t bytes_read) 
     433    { 
     434        Pj_Event_Handler *handler =  
     435            (Pj_Event_Handler*) pj_ioqueue_get_user_data(key); 
     436 
     437        handler->on_read_complete((Pj_Async_Op*)op_key, bytes_read); 
     438    } 
     439 
     440    // 
     441    // Static write completion callback. 
     442    // 
     443    static void write_complete_cb(pj_ioqueue_key_t *key,  
     444                                  pj_ioqueue_op_key_t *op_key, 
     445                                  pj_ssize_t bytes_sent) 
     446    { 
     447        Pj_Event_Handler *handler =  
     448            (Pj_Event_Handler*) pj_ioqueue_get_user_data(key); 
     449 
     450        handler->on_write_complete((Pj_Async_Op*)op_key, bytes_sent); 
     451    } 
     452 
     453    // 
     454    // Static accept completion callback. 
     455    // 
     456    static void accept_complete_cb(pj_ioqueue_key_t *key,  
     457                                   pj_ioqueue_op_key_t *op_key, 
     458                                   pj_sock_t new_sock, 
     459                                   pj_status_t status) 
     460    { 
     461        Pj_Event_Handler *handler =  
     462            (Pj_Event_Handler*) pj_ioqueue_get_user_data(key); 
     463 
     464        handler->on_accept_complete((Pj_Async_Op*)op_key, new_sock, status); 
     465    } 
     466 
     467    // 
     468    // Static connect completion callback. 
     469    // 
     470    static void connect_complete_cb(pj_ioqueue_key_t *key,  
     471                                    pj_status_t status) 
     472    { 
     473        Pj_Event_Handler *handler =  
     474            (Pj_Event_Handler*) pj_ioqueue_get_user_data(key); 
     475 
     476        handler->on_connect_complete(status); 
     477    } 
     478 
    86479}; 
    87480 
    88 #endif  /* __PJPP_EVENT_HANDLER_H__ */ 
     481#endif  /* __PJPP_PROACTOR_H__ */ 
  • pjproject/main/pjlib/include/pj++/scanner.hpp

    r29 r36  
    55#define __PJPP_SCANNER_H__ 
    66 
    7 #include <pj/scanner.h> 
     7#include <pjlib-util/scanner.h> 
    88#include <pj++/string.hpp> 
    99 
    10 class PJ_CharSpec 
     10class Pj_Char_Spec 
    1111{ 
    1212public: 
    13     PJ_CharSpec() { pj_cs_init(cs__); } 
     13    Pj_Char_Spec() { pj_cs_init(cs__); } 
    1414 
    1515    void set(int c) { pj_cs_set(cs__, c); } 
     
    3737}; 
    3838 
    39 class PJ_Scanner 
     39class Pj_Scanner 
    4040{ 
    4141public: 
    42     PJ_Scanner() {} 
     42    Pj_Scanner() {} 
    4343 
    4444    enum 
     
    6868    int peek_char() const 
    6969    { 
    70         return *scanner_.current; 
     70        return *scanner_.curptr; 
    7171    } 
    7272 
    73     int peek(const PJ_CharSpec *cs, PJ_String *out) 
     73    int peek(const Pj_Char_Spec *cs, Pj_String *out) 
    7474    { 
    7575        return pj_scan_peek(&scanner_,  cs->cs_(), out); 
    7676    } 
    7777 
    78     int peek_n(pj_size_t len, PJ_String *out) 
     78    int peek_n(pj_size_t len, Pj_String *out) 
    7979    { 
    8080        return pj_scan_peek_n(&scanner_, len, out); 
    8181    } 
    8282 
    83     int peek_until(const PJ_CharSpec *cs, PJ_String *out) 
     83    int peek_until(const Pj_Char_Spec *cs, Pj_String *out) 
    8484    { 
    8585        return pj_scan_peek_until(&scanner_, cs->cs_(), out); 
    8686    } 
    8787 
    88     void get(const PJ_CharSpec *cs, PJ_String *out) 
     88    void get(const Pj_Char_Spec *cs, Pj_String *out) 
    8989    { 
    9090        pj_scan_get(&scanner_, cs->cs_(), out); 
    9191    } 
    9292 
    93     void get_n(unsigned N, PJ_String *out) 
     93    void get_n(unsigned N, Pj_String *out) 
    9494    { 
    9595        pj_scan_get_n(&scanner_, N, out); 
     
    101101    } 
    102102 
    103     void get_quote(int begin_quote, int end_quote, PJ_String *out) 
     103    void get_quote(int begin_quote, int end_quote, Pj_String *out) 
    104104    { 
    105105        pj_scan_get_quote(&scanner_, begin_quote, end_quote, out); 
     
    111111    } 
    112112 
    113     void get_until(const PJ_CharSpec *cs, PJ_String *out) 
     113    void get_until(const Pj_Char_Spec *cs, Pj_String *out) 
    114114    { 
    115115        pj_scan_get_until(&scanner_, cs->cs_(), out); 
    116116    } 
    117117 
    118     void get_until_ch(int until_ch, PJ_String *out) 
     118    void get_until_ch(int until_ch, Pj_String *out) 
    119119    { 
    120120        pj_scan_get_until_ch(&scanner_, until_ch, out); 
    121121    } 
    122122 
    123     void get_until_chr(const char *spec, PJ_String *out) 
     123    void get_until_chr(const char *spec, Pj_String *out) 
    124124    { 
    125125        pj_scan_get_until_chr(&scanner_, spec, out); 
  • pjproject/main/pjlib/include/pj++/sock.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_SOCK_H__ 
     
    65 
    76#include <pj/sock.h> 
    8  
    9 class PJ_Addr 
     7#include <pj/string.h> 
     8 
     9class Pj_Event_Handler; 
     10 
     11// 
     12// Base class for address. 
     13// 
     14class Pj_Addr 
    1015{ 
    1116}; 
    1217 
    13 class PJ_INET_Addr : public pj_sockaddr_in, public PJ_Addr 
     18// 
     19// Internet address. 
     20// 
     21class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr 
    1422{ 
    1523public: 
     24    // 
     25    // Get port number. 
     26    // 
    1627    pj_uint16_t get_port_number() const 
    1728    { 
    18         return pj_sockaddr_get_port(this); 
    19     } 
    20  
     29        return pj_sockaddr_in_get_port(this); 
     30    } 
     31 
     32    // 
     33    // Set port number. 
     34    // 
    2135    void set_port_number(pj_uint16_t port) 
    2236    { 
    2337        sin_family = PJ_AF_INET; 
    24         pj_sockaddr_set_port(this, port); 
    25     } 
    26  
     38        pj_sockaddr_in_set_port(this, port); 
     39    } 
     40 
     41    // 
     42    // Get IP address. 
     43    // 
    2744    pj_uint32_t get_ip_address() const 
    2845    { 
    29         return pj_sockaddr_get_addr(this); 
    30     } 
    31  
     46        return pj_sockaddr_in_get_addr(this).s_addr; 
     47    } 
     48 
     49    // 
     50    // Get address string. 
     51    // 
    3252    const char *get_address() const 
    3353    { 
    34         return pj_sockaddr_get_str_addr(this); 
    35     } 
    36  
     54        return pj_inet_ntoa(sin_addr); 
     55    } 
     56 
     57    // 
     58    // Set IP address. 
     59    // 
    3760    void set_ip_address(pj_uint32_t addr) 
    3861    { 
    3962        sin_family = PJ_AF_INET; 
    40         pj_sockaddr_set_addr(this, addr); 
    41     } 
    42  
     63        pj_sockaddr_in_set_addr(this, addr); 
     64    } 
     65 
     66    // 
     67    // Set address. 
     68    // 
    4369    pj_status_t set_address(const pj_str_t *addr) 
    4470    { 
    45         return pj_sockaddr_set_str_addr(this, addr); 
    46     } 
    47  
     71        return pj_sockaddr_in_set_str_addr(this, addr); 
     72    } 
     73 
     74    // 
     75    // Set address. 
     76    // 
    4877    pj_status_t set_address(const char *addr) 
    4978    { 
    50         return pj_sockaddr_set_str_addr2(this, addr); 
    51     } 
    52  
    53     int cmp(const PJ_INET_Addr &rhs) const 
    54     { 
    55         return pj_sockaddr_cmp(this, &rhs); 
    56     } 
    57  
    58     bool operator==(const PJ_INET_Addr &rhs) const 
    59     { 
    60         return cmp(rhs) == 0; 
    61     } 
     79        pj_str_t s; 
     80        return pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr)); 
     81    } 
     82 
     83    // 
     84    // Compare for equality. 
     85    // 
     86    bool operator==(const Pj_Inet_Addr &rhs) const 
     87    { 
     88        return sin_family == rhs.sin_family && 
     89               sin_addr.s_addr == rhs.sin_addr.s_addr && 
     90               sin_port == rhs.sin_port; 
     91    } 
     92 
     93private: 
     94    // 
     95    // Dummy length used in pj_ioqueue_recvfrom() etc 
     96    // 
     97    friend class Pj_Event_Handler; 
     98    friend class Pj_Socket; 
     99    friend class Pj_Sock_Stream; 
     100    friend class Pj_Sock_Dgram; 
     101 
     102    int addrlen_; 
    62103}; 
    63104 
    64 class PJ_Socket 
     105 
     106// 
     107// Socket base class. 
     108// 
     109// Note: 
     110//  socket will not automatically be closed on destructor. 
     111// 
     112class Pj_Socket 
    65113{ 
    66114public: 
    67     PJ_Socket() {} 
    68     PJ_Socket(const PJ_Socket &rhs) : sock_(rhs.sock_) {} 
    69  
     115    // 
     116    // Default constructor. 
     117    // 
     118    Pj_Socket() 
     119        : sock_(PJ_INVALID_SOCKET)  
     120    { 
     121    } 
     122 
     123    // 
     124    // Initialize from a socket handle. 
     125    // 
     126    explicit Pj_Socket(pj_sock_t sock) 
     127        : sock_(sock) 
     128    { 
     129    } 
     130 
     131    // 
     132    // Copy constructor. 
     133    // 
     134    Pj_Socket(const Pj_Socket &rhs)  
     135        : sock_(rhs.sock_)  
     136    { 
     137    } 
     138 
     139    // 
     140    // Destructor will not close the socket. 
     141    // You must call close() explicitly. 
     142    // 
     143    ~Pj_Socket() 
     144    { 
     145    } 
     146 
     147    // 
     148    // Set socket handle. 
     149    // 
    70150    void set_handle(pj_sock_t sock) 
    71151    { 
     
    73153    } 
    74154 
     155    // 
     156    // Get socket handle. 
     157    // 
    75158    pj_sock_t get_handle() const 
    76159    { 
     
    78161    } 
    79162 
     163    // 
     164    // Get socket handle. 
     165    // 
    80166    pj_sock_t& get_handle() 
    81167    { 
     
    83169    } 
    84170 
    85     bool socket(int af, int type, int proto, pj_uint32_t flag=0) 
    86     { 
    87         sock_ = pj_sock_socket(af, type, proto, flag); 
    88         return sock_ != -1; 
    89     } 
    90  
    91     bool bind(const PJ_INET_Addr &addr) 
    92     { 
    93         return pj_sock_bind(sock_, &addr, sizeof(PJ_INET_Addr)) == 0; 
    94     } 
    95  
    96     bool close() 
    97     { 
    98         return pj_sock_close(sock_) == 0; 
    99     } 
    100  
    101     bool getpeername(PJ_INET_Addr *addr) 
    102     { 
    103         int namelen; 
    104         return pj_sock_getpeername(sock_, addr, &namelen) == 0; 
    105     } 
    106  
    107     bool getsockname(PJ_INET_Addr *addr) 
    108     { 
    109         int namelen; 
    110         return pj_sock_getsockname(sock_, addr, &namelen) == 0; 
    111     } 
    112  
    113     bool getsockopt(int level, int optname, void *optval, int *optlen) 
    114     { 
    115         return pj_sock_getsockopt(sock_, level, optname, optval, optlen) == 0; 
    116     } 
    117  
    118     bool setsockopt(int level, int optname, const void *optval, int optlen) 
    119     { 
    120         return pj_sock_setsockopt(sock_, level, optname, optval, optlen) == 0; 
    121     } 
    122  
    123     bool ioctl(long cmd, pj_uint32_t *val) 
    124     { 
    125         return pj_sock_ioctl(sock_, cmd, val) == 0; 
    126     } 
    127  
    128     int recv(void *buf, int len, int flag = 0) 
    129     { 
    130         return pj_sock_recv(sock_, buf, len, flag); 
    131     } 
    132  
    133     int send(const void *buf, int len, int flag = 0) 
    134     { 
    135         return pj_sock_send(sock_, buf, len, flag); 
     171    // 
     172    // See if the socket is valid. 
     173    // 
     174    bool is_valid() const 
     175    { 
     176        return sock_ != PJ_INVALID_SOCKET; 
     177    } 
     178 
     179    // 
     180    // Create the socket. 
     181    // 
     182    pj_status_t create(int af, int type, int proto) 
     183    { 
     184        return pj_sock_socket(af, type, proto, &sock_); 
     185    } 
     186 
     187    // 
     188    // Bind socket. 
     189    // 
     190    pj_status_t bind(const Pj_Inet_Addr &addr) 
     191    { 
     192        return pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr)); 
     193    } 
     194 
     195    // 
     196    // Close socket. 
     197    // 
     198    pj_status_t close() 
     199    { 
     200        pj_sock_close(sock_); 
     201    } 
     202 
     203    // 
     204    // Get peer socket name. 
     205    // 
     206    pj_status_t getpeername(Pj_Inet_Addr *addr) 
     207    { 
     208        return pj_sock_getpeername(sock_, addr, &addr->addrlen_); 
     209    } 
     210 
     211    // 
     212    // getsockname 
     213    // 
     214    pj_status_t getsockname(Pj_Inet_Addr *addr) 
     215    { 
     216        return pj_sock_getsockname(sock_, addr, &addr->addrlen_); 
     217    } 
     218 
     219    // 
     220    // getsockopt. 
     221    // 
     222    pj_status_t getsockopt(int level, int optname,  
     223                           void *optval, int *optlen) 
     224    { 
     225        return pj_sock_getsockopt(sock_, level, optname, optval, optlen); 
     226    } 
     227 
     228    // 
     229    // setsockopt 
     230    //  
     231    pj_status_t setsockopt(int level, int optname,  
     232                           const void *optval, int optlen) 
     233    { 
     234        return pj_sock_setsockopt(sock_, level, optname, optval, optlen); 
     235    } 
     236 
     237    // 
     238    // receive data. 
     239    // 
     240    pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0) 
     241    { 
     242        pj_ssize_t bytes = len; 
     243        if (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS) 
     244            return -1; 
     245        return bytes; 
     246    } 
     247 
     248    // 
     249    // send data. 
     250    // 
     251    pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0) 
     252    { 
     253        pj_ssize_t bytes = len; 
     254        if (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS) 
     255            return -1; 
     256        return bytes; 
     257    } 
     258 
     259    // 
     260    // connect. 
     261    // 
     262    pj_status_t connect(const Pj_Inet_Addr &addr) 
     263    { 
     264        return pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr)); 
     265    } 
     266 
     267    // 
     268    // assignment. 
     269    // 
     270    Pj_Socket &operator=(const Pj_Socket &rhs) 
     271    { 
     272        sock_ = rhs.sock_; 
     273        return *this; 
    136274    } 
    137275 
    138276protected: 
     277    friend class Pj_Event_Handler; 
    139278    pj_sock_t sock_; 
    140279}; 
    141280 
     281 
    142282#if PJ_HAS_TCP 
    143 class PJ_Sock_Stream : public PJ_Socket 
     283// 
     284// Stream socket. 
     285// 
     286class Pj_Sock_Stream : public Pj_Socket 
    144287{ 
    145288public: 
    146     PJ_Sock_Stream() {} 
    147     PJ_Sock_Stream(const PJ_Sock_Stream &rhs) : PJ_Socket(rhs) {} 
    148     PJ_Sock_Stream &operator=(const PJ_Sock_Stream &rhs) { sock_ = rhs.sock_; return *this; } 
    149  
    150     bool listen(int backlog = 5) 
    151     { 
    152         return pj_sock_listen(sock_, backlog) == 0; 
    153     } 
    154  
    155     bool accept(PJ_Sock_Stream *new_sock, PJ_INET_Addr *addr, int *addrlen) 
    156     { 
    157         pj_sock_t s = pj_sock_accept(sock_, addr, addrlen); 
    158         if (s == -1) 
    159             return false; 
    160         new_sock->set_handle(s); 
    161         return true; 
    162     } 
    163  
    164     bool connect(const PJ_INET_Addr &addr) 
    165     { 
    166         return pj_sock_connect(sock_, &addr, sizeof(PJ_INET_Addr)) == 0; 
    167     } 
    168  
    169     bool shutdown(int how) 
    170     { 
    171         return pj_sock_shutdown(sock_, how) == 0; 
     289    // 
     290    // Default constructor. 
     291    // 
     292    Pj_Sock_Stream()  
     293    { 
     294    } 
     295 
     296    // 
     297    // Initialize from a socket handle. 
     298    // 
     299    explicit Pj_Sock_Stream(pj_sock_t sock) 
     300        : Pj_Socket(sock) 
     301    { 
     302    } 
     303 
     304    // 
     305    // Copy constructor. 
     306    // 
     307    Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs)  
     308    { 
     309    } 
     310 
     311    // 
     312    // Assignment. 
     313    // 
     314    Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs)  
     315    {  
     316        sock_ = rhs.sock_;  
     317        return *this;  
     318    } 
     319 
     320    // 
     321    // listen() 
     322    // 
     323    pj_status_t listen(int backlog = 5) 
     324    { 
     325        return pj_sock_listen(sock_, backlog); 
     326    } 
     327 
     328    // 
     329    // blocking accept() 
     330    // 
     331    Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL) 
     332    { 
     333        pj_sock_t newsock; 
     334        int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL; 
     335        pj_status_t status; 
     336         
     337        status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen); 
     338        if (status != PJ_SUCCESS) 
     339            return Pj_Sock_Stream(-1); 
     340 
     341        return Pj_Sock_Stream(newsock); 
     342    } 
     343 
     344    // 
     345    // shutdown() 
     346    // 
     347    pj_status_t shutdown(int how = PJ_SHUT_RDWR) 
     348    { 
     349        return pj_sock_shutdown(sock_, how); 
    172350    } 
    173351 
     
    175353#endif 
    176354 
    177 class PJ_Sock_Dgram : public PJ_Socket 
     355// 
     356// Datagram socket. 
     357// 
     358class Pj_Sock_Dgram : public Pj_Socket 
    178359{ 
    179360public: 
    180     PJ_Sock_Dgram() {} 
    181     PJ_Sock_Dgram(const PJ_Sock_Dgram &rhs) : PJ_Socket(rhs) {} 
    182     PJ_Sock_Dgram &operator=(const PJ_Sock_Dgram &rhs) { sock_ = rhs.sock_; return *this; } 
    183  
    184     int recvfrom(void *buf, int len, int flag, PJ_INET_Addr *fromaddr) 
    185     { 
    186         int addrlen; 
    187         return pj_sock_recvfrom(sock_, buf, len, flag, fromaddr, &addrlen); 
    188     } 
    189  
    190     int sendto(const void *buf, int len, int flag, const PJ_INET_Addr &addr) 
    191     { 
    192         return pj_sock_sendto(sock_, buf, len, flag, &addr, sizeof(PJ_INET_Addr)); 
     361    // 
     362    // Default constructor. 
     363    // 
     364    Pj_Sock_Dgram()  
     365    { 
     366    } 
     367 
     368    // 
     369    // Initialize from a socket handle. 
     370    // 
     371    explicit Pj_Sock_Dgram(pj_sock_t sock) 
     372        : Pj_Socket(sock) 
     373    { 
     374    } 
     375 
     376    // 
     377    // Copy constructor. 
     378    // 
     379    Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs)  
     380        : Pj_Socket(rhs)  
     381    { 
     382    } 
     383 
     384    // 
     385    // Assignment. 
     386    // 
     387    Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs)  
     388    {  
     389        Pj_Socket::operator =(rhs); 
     390        return *this;  
     391    } 
     392 
     393    // 
     394    // recvfrom() 
     395    // 
     396    pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0,  
     397                         Pj_Inet_Addr *fromaddr = NULL) 
     398    { 
     399        pj_ssize_t bytes = len; 
     400        int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL; 
     401        if (pj_sock_recvfrom( sock_, buf, &bytes, flag,  
     402                              fromaddr, addrlen) != PJ_SUCCESS) 
     403        { 
     404            return -1; 
     405        } 
     406        return bytes; 
     407    } 
     408 
     409    // 
     410    // sendto() 
     411    // 
     412    pj_ssize_t sendto( const void *buf, pj_size_t len, int flag,  
     413                       const Pj_Inet_Addr &addr) 
     414    { 
     415        pj_ssize_t bytes = len; 
     416        if (pj_sock_sendto( sock_, buf, &bytes, flag,  
     417                            &addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS) 
     418        { 
     419            return -1; 
     420        } 
     421        return bytes; 
    193422    } 
    194423}; 
    195424 
     425 
    196426#endif  /* __PJPP_SOCK_H__ */ 
  • pjproject/main/pjlib/include/pj++/string.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_STRING_H__ 
     
    76#include <pj/string.h> 
    87#include <pj++/pool.hpp> 
    9  
    10 class PJ_String : public pj_str_t 
     8#include <pj/assert.h> 
     9 
     10// 
     11// String wrapper class for pj_str_t. 
     12// 
     13class Pj_String : public pj_str_t 
    1114{ 
    1215public: 
    13     PJ_String()  
     16    // 
     17    // Default constructor. 
     18    // 
     19    Pj_String()  
    1420    {  
    15         pj_assert(sizeof(PJ_String) == sizeof(pj_str_t)); 
    16         ptr=NULL; slen=0;  
    17     } 
    18  
    19     explicit PJ_String(char *str)  
     21        pj_assert(sizeof(Pj_String) == sizeof(pj_str_t)); 
     22        ptr=NULL;  
     23        slen=0;  
     24    } 
     25 
     26    // 
     27    // Construct the buffer from a char*. 
     28    // 
     29    explicit Pj_String(char *str)  
    2030    {  
    2131        set(str); 
    2232    } 
    2333 
    24     PJ_String(PJ_Pool *pool, const char *src) 
     34    // 
     35    // Construct from a const char*. 
     36    // 
     37    Pj_String(Pj_Pool *pool, const char *src) 
    2538    { 
    2639        set(pool, src); 
    2740    } 
    2841 
    29     explicit PJ_String(pj_str_t *s) 
     42    // 
     43    // Construct from pj_str_t*. 
     44    // 
     45    explicit Pj_String(pj_str_t *s) 
    3046    { 
    3147        set(s); 
    3248    } 
    3349 
    34     PJ_String(PJ_Pool *pool, const pj_str_t *s) 
     50    // 
     51    // Construct by copying from const pj_str_t*. 
     52    // 
     53    Pj_String(Pj_Pool *pool, const pj_str_t *s) 
    3554    { 
    3655        set(pool, s); 
    3756    } 
    3857 
    39     explicit PJ_String(PJ_String &rhs) 
     58    // 
     59    // Construct from another Pj_String 
     60    // 
     61    explicit Pj_String(Pj_String &rhs) 
    4062    { 
    4163        set(rhs); 
    4264    } 
    4365 
    44     PJ_String(PJ_Pool *pool, const PJ_String &rhs) 
     66    // 
     67    // Construct by copying from Pj_String 
     68    // 
     69    Pj_String(Pj_Pool *pool, const Pj_String &rhs) 
    4570    { 
    4671        set(pool, rhs); 
    4772    } 
    4873 
    49     PJ_String(char *str, pj_size_t len) 
     74    // 
     75    // Construct from a char* and a length. 
     76    // 
     77    Pj_String(char *str, pj_size_t len) 
    5078    { 
    5179        set(str, len); 
    5280    } 
    5381 
    54     PJ_String(char *begin, char *end) 
     82    // 
     83    // Construct from pair of pointer. 
     84    // 
     85    Pj_String(char *begin, char *end) 
    5586    { 
    5687        pj_strset3(this, begin, end); 
    5788    } 
    5889 
     90    // 
     91    // Get the length of the string. 
     92    // 
    5993    pj_size_t length() const 
    6094    { 
     
    6296    } 
    6397 
     98    // 
     99    // Get the length of the string. 
     100    // 
    64101    pj_size_t size() const 
    65102    { 
     
    67104    } 
    68105 
     106    // 
     107    // Get the string buffer. 
     108    // 
    69109    const char *buf() const 
    70110    { 
     
    72112    } 
    73113 
     114    // 
     115    // Initialize buffer from char*. 
     116    // 
    74117    void set(char *str) 
    75118    { 
     
    77120    } 
    78121 
    79     void set(PJ_Pool *pool, const char *s) 
     122    // 
     123    // Initialize by copying from a const char*. 
     124    // 
     125    void set(Pj_Pool *pool, const char *s) 
    80126    { 
    81127        pj_strdup2(pool->pool_(), this, s); 
    82128    } 
    83129 
     130    // 
     131    // Initialize from pj_str_t*. 
     132    // 
    84133    void set(pj_str_t *s) 
    85134    { 
     
    87136    } 
    88137 
    89     void set(PJ_Pool *pool, const pj_str_t *s) 
     138    // 
     139    // Initialize by copying from const pj_str_t*. 
     140    // 
     141    void set(Pj_Pool *pool, const pj_str_t *s) 
    90142    { 
    91143        pj_strdup(pool->pool_(), this, s); 
    92144    } 
    93145 
     146    // 
     147    // Initialize from char* and length. 
     148    // 
    94149    void set(char *str, pj_size_t len) 
    95150    { 
     
    97152    } 
    98153 
     154    // 
     155    // Initialize from pair of pointers. 
     156    // 
    99157    void set(char *begin, char *end) 
    100158    { 
     
    102160    } 
    103161 
    104     void set(PJ_String &rhs) 
     162    // 
     163    // Initialize from other Pj_String. 
     164    // 
     165    void set(Pj_String &rhs) 
    105166    { 
    106167        pj_strassign(this, &rhs); 
    107168    } 
    108169 
    109     void set(PJ_Pool *pool, const PJ_String *s) 
     170    // 
     171    // Initialize by copying from a Pj_String*. 
     172    // 
     173    void set(Pj_Pool *pool, const Pj_String *s) 
    110174    { 
    111175        pj_strdup(pool->pool_(), this, s); 
    112176    } 
    113177 
    114     void set(PJ_Pool *pool, const PJ_String &s) 
     178    // 
     179    // Initialize by copying from other Pj_String. 
     180    // 
     181    void set(Pj_Pool *pool, const Pj_String &s) 
    115182    { 
    116183        pj_strdup(pool->pool_(), this, &s); 
    117184    } 
    118185 
     186    // 
     187    // Copy the contents of other string. 
     188    // 
    119189    void strcpy(const pj_str_t *s) 
    120190    { 
     
    122192    } 
    123193 
    124     void strcpy(const PJ_String &rhs) 
     194    // 
     195    // Copy the contents of other string. 
     196    // 
     197    void strcpy(const Pj_String &rhs) 
    125198    { 
    126199        pj_strcpy(this, &rhs); 
    127200    } 
    128201 
     202    // 
     203    // Copy the contents of other string. 
     204    // 
    129205    void strcpy(const char *s) 
    130206    { 
     
    132208    } 
    133209 
     210    // 
     211    // Compare string. 
     212    // 
    134213    int strcmp(const char *s) const 
    135214    { 
     
    137216    } 
    138217 
     218    // 
     219    // Compare string. 
     220    // 
    139221    int strcmp(const pj_str_t *s) const 
    140222    { 
     
    142224    } 
    143225 
    144     int strcmp(const PJ_String &rhs) const 
     226    // 
     227    // Compare string. 
     228    // 
     229    int strcmp(const Pj_String &rhs) const 
    145230    { 
    146231        return pj_strcmp(this, &rhs); 
    147232    } 
    148233 
     234    // 
     235    // Compare string. 
     236    // 
    149237    int strncmp(const char *s, pj_size_t len) const 
    150238    { 
     
    152240    } 
    153241 
     242    // 
     243    // Compare string. 
     244    // 
    154245    int strncmp(const pj_str_t *s, pj_size_t len) const 
    155246    { 
     
    157248    } 
    158249 
    159     int strncmp(const PJ_String &rhs, pj_size_t len) const 
     250    // 
     251    // Compare string. 
     252    // 
     253    int strncmp(const Pj_String &rhs, pj_size_t len) const 
    160254    { 
    161255        return pj_strncmp(this, &rhs, len); 
    162256    } 
    163257 
     258    // 
     259    // Compare string. 
     260    // 
    164261    int stricmp(const char *s) const 
    165262    { 
     
    167264    } 
    168265 
     266    // 
     267    // Compare string. 
     268    // 
    169269    int stricmp(const pj_str_t *s) const 
    170270    { 
     
    172272    } 
    173273 
    174     int stricmp(const PJ_String &rhs) const 
     274    // 
     275    // Compare string. 
     276    // 
     277    int stricmp(const Pj_String &rhs) const 
    175278    { 
    176279        return stricmp(&rhs); 
    177280    } 
    178281 
     282    // 
     283    // Compare string. 
     284    // 
    179285    int strnicmp(const char *s, pj_size_t len) const 
    180286    { 
     
    182288    } 
    183289 
     290    // 
     291    // Compare string. 
     292    // 
    184293    int strnicmp(const pj_str_t *s, pj_size_t len) const 
    185294    { 
     
    187296    } 
    188297 
    189     int strnicmp(const PJ_String &rhs, pj_size_t len) const 
     298    // 
     299    // Compare string. 
     300    // 
     301    int strnicmp(const Pj_String &rhs, pj_size_t len) const 
    190302    { 
    191303        return strnicmp(&rhs, len); 
    192304    } 
    193305 
     306    // 
     307    // Compare contents for equality. 
     308    // 
    194309    bool operator==(const char *s) const 
    195310    { 
     
    197312    } 
    198313 
     314    // 
     315    // Compare contents for equality. 
     316    // 
    199317    bool operator==(const pj_str_t *s) const 
    200318    { 
     
    202320    } 
    203321 
    204     bool operator==(const PJ_String &rhs) const 
     322    // 
     323    // Compare contents for equality. 
     324    // 
     325    bool operator==(const Pj_String &rhs) const 
    205326    { 
    206327        return pj_strcmp(this, &rhs) == 0; 
    207328    } 
    208329 
     330    // 
     331    // Find a character in the string. 
     332    // 
    209333    char *strchr(int chr) 
    210334    { 
     
    212336    } 
    213337 
     338    // 
     339    // Find a character in the string. 
     340    // 
    214341    char *find(int chr) 
    215342    { 
     
    217344    } 
    218345 
    219     void strcat(const PJ_String &rhs) 
     346    // 
     347    // Concatenate string. 
     348    // 
     349    void strcat(const Pj_String &rhs) 
    220350    { 
    221351        pj_strcat(this, &rhs); 
    222352    } 
    223353 
     354    // 
     355    // Left trim. 
     356    // 
    224357    void ltrim() 
    225358    { 
     
    227360    } 
    228361 
     362    // 
     363    // Right trim. 
     364    // 
    229365    void rtrim() 
    230366    { 
     
    232368    } 
    233369 
     370    // 
     371    // Left and right trim. 
     372    // 
    234373    void trim() 
    235374    { 
     
    237376    } 
    238377 
    239     unsigned long toul() const 
     378    // 
     379    // Convert to unsigned long. 
     380    // 
     381    unsigned long to_ulong() const 
    240382    { 
    241383        return pj_strtoul(this); 
    242384    } 
    243385 
     386    // 
     387    // Convert from unsigned long. 
     388    // 
     389    void from_ulong(unsigned long value) 
     390    { 
     391        slen = pj_utoa(value, ptr); 
     392    } 
     393 
     394    // 
     395    // Convert from unsigned long with padding. 
     396    // 
     397    void from_ulong_with_pad(unsigned long value, int min_dig=0, int pad=' ') 
     398    { 
     399        slen = pj_utoa_pad(value, ptr, min_dig, pad); 
     400    } 
     401 
     402 
    244403private: 
    245     //PJ_String(const PJ_String &rhs) {} 
    246     void operator=(const PJ_String &rhs) { pj_assert(false); } 
     404    //Pj_String(const Pj_String &rhs) {} 
     405    void operator=(const Pj_String &rhs) { pj_assert(false); } 
    247406}; 
    248407 
  • pjproject/main/pjlib/include/pj++/timer.hpp

    r29 r36  
    11/* $Id$ 
    2  * 
    32 */ 
    43#ifndef __PJPP_TIMER_H__ 
     
    76#include <pj/timer.h> 
    87#include <pj++/types.hpp> 
     8#include <pj/assert.h> 
     9#include <pj++/lock.hpp> 
    910 
    10 class PJ_Timer_Heap; 
     11class Pj_Timer_Heap; 
    1112 
    12 class PJ_Timer_Entry : private pj_timer_entry 
     13////////////////////////////////////////////////////////////////////////////// 
     14// Timer entry. 
     15// 
     16// How to use: 
     17//  Derive class from Pj_Timer_Entry and override on_timeout(). 
     18//  Scheduler timer in Pj_Timer_Heap. 
     19// 
     20class Pj_Timer_Entry : public Pj_Object 
    1321{ 
    14     friend class PJ_Timer_Heap; 
     22    friend class Pj_Timer_Heap; 
    1523 
    1624public: 
    17     static void timer_heap_callback(pj_timer_heap_t *, pj_timer_entry *); 
    18  
    19     PJ_Timer_Entry() { cb = &timer_heap_callback; } 
    20     PJ_Timer_Entry(int arg_id, void *arg_user_data) 
    21     { 
    22         cb = &timer_heap_callback;  
    23         init(arg_id, arg_user_data); 
     25    // 
     26    // Default constructor. 
     27    // 
     28    Pj_Timer_Entry()  
     29    {  
     30        entry_.user_data = this; 
     31        entry_.cb = &timer_heap_callback;  
    2432    } 
    2533 
    26     virtual void on_timeout() = 0; 
    27  
    28     void init(int arg_id, void *arg_user_data) 
     34    // 
     35    // Destructor, do nothing. 
     36    // 
     37    ~Pj_Timer_Entry() 
    2938    { 
    30         id = arg_id; 
    31         user_data = arg_user_data; 
    3239    } 
    3340 
    34     int get_id() const 
     41    // 
     42    // Override this to get the timeout notification. 
     43    // 
     44    virtual void on_timeout(int id) = 0; 
     45 
     46private: 
     47    pj_timer_entry entry_; 
     48 
     49    static void timer_heap_callback(pj_timer_heap_t *th, pj_timer_entry *e) 
    3550    { 
    36         return id; 
     51        Pj_Timer_Entry *entry = (Pj_Timer_Entry*) e->user_data; 
     52        entry->on_timeout(e->id); 
    3753    } 
    3854 
    39     void set_id(int arg_id) 
     55}; 
     56 
     57////////////////////////////////////////////////////////////////////////////// 
     58// Timer heap. 
     59// 
     60class Pj_Timer_Heap : public Pj_Object 
     61{ 
     62public: 
     63    // 
     64    // Default constructor. 
     65    // 
     66    Pj_Timer_Heap()  
     67        : ht_(NULL)  
    4068    { 
    41         id = arg_id; 
    4269    } 
    4370 
    44     void set_user_data(void *arg_user_data) 
     71    // 
     72    // Construct timer heap. 
     73    // 
     74    Pj_Timer_Heap(Pj_Pool *pool, pj_size_t initial_count) 
     75        : ht_(NULL) 
    4576    { 
    46         user_data = arg_user_data; 
     77        create(pool, initial_count); 
    4778    } 
    4879 
    49     void *get_user_data() const 
     80    // 
     81    // Destructor. 
     82    // 
     83    ~Pj_Timer_Heap() 
    5084    { 
    51         return user_data; 
     85        destroy(); 
    5286    } 
    5387 
    54     const PJ_Time_Val &get_timeout() const 
     88    // 
     89    // Create 
     90    //  
     91    pj_status_t create(Pj_Pool *pool, pj_size_t initial_count) 
    5592    { 
    56         pj_assert(sizeof(PJ_Time_Val) == sizeof(pj_time_val)); 
    57         return (PJ_Time_Val&)_timer_value; 
    58     } 
    59 }; 
    60  
    61 class PJ_Timer_Heap 
    62 { 
    63 public: 
    64     PJ_Timer_Heap() {} 
    65  
    66     bool create(PJ_Pool *pool, pj_size_t initial_count,  
    67                 unsigned flag = PJ_TIMER_HEAP_SYNCHRONIZE) 
    68     { 
    69         ht_ = pj_timer_heap_create(pool->pool_(), initial_count, flag); 
    70         return ht_ != NULL; 
     93        destroy(); 
     94        return pj_timer_heap_create(pool->pool_(), initial_count, &ht_); 
    7195    } 
    7296 
     97    // 
     98    // Destroy 
     99    // 
     100    void destroy() 
     101    { 
     102        if (ht_) { 
     103            pj_timer_heap_destroy(ht_); 
     104            ht_ = NULL; 
     105        } 
     106    } 
     107 
     108    // 
     109    // Get pjlib compatible timer heap object. 
     110    // 
    73111    pj_timer_heap_t *get_timer_heap() 
    74112    { 
     
    76114    } 
    77115 
    78     bool schedule( PJ_Timer_Entry *ent, const PJ_Time_Val &delay) 
     116    // 
     117    // Set the lock object. 
     118    // 
     119    void set_lock( Pj_Lock *lock, bool auto_delete ) 
    79120    { 
    80         return pj_timer_heap_schedule(ht_, ent, &delay) == 0; 
     121        pj_timer_heap_set_lock( ht_, lock->pj_lock_t_(), auto_delete); 
    81122    } 
    82123 
    83     bool cancel(PJ_Timer_Entry *ent) 
     124    // 
     125    // Set maximum number of timed out entries to be processed per poll. 
     126    // 
     127    unsigned set_max_timed_out_per_poll(unsigned count) 
    84128    { 
    85         return pj_timer_heap_cancel(ht_, ent) == 1; 
     129        return pj_timer_heap_set_max_timed_out_per_poll(ht_, count); 
    86130    } 
    87131 
     132    // 
     133    // Schedule a timer. 
     134    // 
     135    bool schedule( Pj_Timer_Entry *ent, const Pj_Time_Val &delay, 
     136                   int id) 
     137    { 
     138        ent->entry_.id = id; 
     139        return pj_timer_heap_schedule(ht_, &ent->entry_, &delay) == 0; 
     140    } 
     141 
     142    // 
     143    // Cancel a timer. 
     144    // 
     145    bool cancel(Pj_Timer_Entry *ent) 
     146    { 
     147        return pj_timer_heap_cancel(ht_, &ent->entry_) == 1; 
     148    } 
     149 
     150    // 
     151    // Get current number of timers 
     152    // 
    88153    pj_size_t count() 
    89154    { 
     
    91156    } 
    92157 
    93     void earliest_time(PJ_Time_Val *t) 
     158    // 
     159    // Get the earliest time. 
     160    // Return false if no timer is found. 
     161    // 
     162    bool earliest_time(Pj_Time_Val *t) 
    94163    { 
    95         pj_timer_heap_earliest_time(ht_, t); 
     164        return pj_timer_heap_earliest_time(ht_, t) == PJ_SUCCESS; 
    96165    } 
    97166 
    98     int poll(PJ_Time_Val *next_delay = NULL) 
     167    // 
     168    // Poll the timer. 
     169    // Return number of timed out entries has been called. 
     170    // 
     171    unsigned poll(Pj_Time_Val *next_delay = NULL) 
    99172    { 
    100173        return pj_timer_heap_poll(ht_, next_delay); 
  • pjproject/main/pjlib/include/pj++/tree.hpp

    r29 r36  
    77#include <pj/rbtree.h> 
    88 
     9// 
     10// Tree. 
     11// 
    912class PJ_Tree 
    1013{ 
  • pjproject/main/pjlib/include/pj++/types.hpp

    r29 r36  
    77#include <pj/types.h> 
    88 
    9 class PJ_Pool; 
    10 class PJ_Socket; 
     9class Pj_Pool; 
     10class Pj_Socket ; 
     11class Pj_Lock; 
    1112 
    1213 
    13 class PJ_Time_Val : public pj_time_val 
     14// 
     15// PJLIB initializer. 
     16// 
     17class Pjlib 
    1418{ 
    1519public: 
    16     PJ_Time_Val() {} 
    17     PJ_Time_Val(const PJ_Time_Val &rhs) { sec=rhs.sec; msec=rhs.msec; } 
    18     explicit PJ_Time_Val(const pj_time_val &tv) { sec = tv.sec; msec = tv.msec; } 
     20    Pjlib() 
     21    { 
     22        pj_init(); 
     23    } 
     24}; 
    1925 
    20     long get_sec()  const    { return sec; } 
    21     long get_msec() const    { return msec; } 
    22     void set_sec (long s)    { sec = s; } 
    23     void set_msec(long ms)   { msec = ms; normalize(); } 
    24     long to_msec() const { return PJ_TIME_VAL_MSEC((*this)); } 
     26// 
     27// Class Pj_Object is declared in pool.hpp 
     28// 
    2529 
    26     bool operator == (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_EQ((*this), rhs);  } 
    27     bool operator >  (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_GT((*this), rhs);  } 
    28     bool operator >= (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_GTE((*this), rhs); } 
    29     bool operator <  (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_LT((*this), rhs);  } 
    30     bool operator <= (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_LTE((*this), rhs); } 
     30// 
     31// Time value wrapper. 
     32// 
     33class Pj_Time_Val : public pj_time_val 
     34{ 
     35public: 
     36    Pj_Time_Val() 
     37    { 
     38    } 
    3139 
    32     PJ_Time_Val & operator = (const PJ_Time_Val &rhs) { 
     40    Pj_Time_Val(long init_sec, long init_msec) 
     41    { 
     42        sec = init_sec; 
     43        msec = init_msec; 
     44    } 
     45 
     46    Pj_Time_Val(const Pj_Time_Val &rhs)  
     47    {  
     48        sec=rhs.sec;  
     49        msec=rhs.msec;  
     50    } 
     51 
     52    explicit Pj_Time_Val(const pj_time_val &tv)  
     53    {  
     54        sec = tv.sec;  
     55        msec = tv.msec;  
     56    } 
     57 
     58    long get_sec()  const     
     59    {  
     60        return sec;  
     61    } 
     62 
     63    long get_msec() const     
     64    {  
     65        return msec;  
     66    } 
     67 
     68    void set_sec (long s)     
     69    {  
     70        sec = s;  
     71    } 
     72 
     73    void set_msec(long ms)    
     74    {  
     75        msec = ms;  
     76        normalize();  
     77    } 
     78 
     79    long to_msec() const  
     80    {  
     81        return PJ_TIME_VAL_MSEC((*this));  
     82    } 
     83 
     84    bool operator == (const Pj_Time_Val &rhs) const  
     85    {  
     86        return PJ_TIME_VAL_EQ((*this), rhs);   
     87    } 
     88 
     89    bool operator >  (const Pj_Time_Val &rhs) const  
     90    {  
     91        return PJ_TIME_VAL_GT((*this), rhs);   
     92    } 
     93 
     94    bool operator >= (const Pj_Time_Val &rhs) const  
     95    {  
     96        return PJ_TIME_VAL_GTE((*this), rhs);  
     97    } 
     98 
     99    bool operator <  (const Pj_Time_Val &rhs) const  
     100    {  
     101        return PJ_TIME_VAL_LT((*this), rhs);   
     102    } 
     103 
     104    bool operator <= (const Pj_Time_Val &rhs) const  
     105    {  
     106        return PJ_TIME_VAL_LTE((*this), rhs);  
     107    } 
     108 
     109    Pj_Time_Val & operator = (const Pj_Time_Val &rhs)  
     110    { 
    33111        sec = rhs.sec; 
    34112        msec = rhs.msec; 
     
    36114    } 
    37115  
    38     PJ_Time_Val & operator += (const PJ_Time_Val &rhs) { 
     116    Pj_Time_Val & operator += (const Pj_Time_Val &rhs)  
     117    { 
    39118        PJ_TIME_VAL_ADD((*this), rhs); 
    40119        return *this; 
    41120    } 
    42121 
    43     PJ_Time_Val & operator -= (const PJ_Time_Val &rhs) { 
     122    Pj_Time_Val & operator -= (const Pj_Time_Val &rhs)  
     123    { 
    44124        PJ_TIME_VAL_SUB((*this), rhs); 
    45125        return *this; 
     
    47127 
    48128    /* Must include os.hpp to use these, otherwise unresolved in linking */ 
    49     pj_status_t    gettimeofday(); 
    50     pj_parsed_time decode(); 
    51     pj_status_t    encode(const pj_parsed_time *pt); 
    52     pj_status_t    to_gmt(); 
    53     pj_status_t    to_local(); 
     129    inline pj_status_t     gettimeofday(); 
     130    inline pj_parsed_time decode(); 
     131    inline pj_status_t     encode(const pj_parsed_time *pt); 
     132    inline pj_status_t     to_gmt(); 
     133    inline pj_status_t     to_local(); 
    54134 
    55135 
    56136private: 
    57     void normalize() { pj_time_val_normalize(this); } 
     137    void normalize()  
     138    {  
     139        pj_time_val_normalize(this);  
     140    } 
    58141 
    59142}; 
  • pjproject/main/pjlib/include/pj/errno.h

    r4 r36  
    211211 */ 
    212212#define PJ_EINVALIDOP       (PJ_ERRNO_START_STATUS + 13) 
     213/** 
     214 * @hideinitializer 
     215 * Operation is cancelled. 
     216 */ 
     217#define PJ_ECANCELLED       (PJ_ERRNO_START_STATUS + 14) 
    213218 
    214219/** @} */   /* pj_errnum */ 
  • pjproject/main/pjlib/include/pj/ioqueue.h

    r19 r36  
    298298/** 
    299299 * Unregister from the I/O Queue framework. Caller must make sure that 
    300  * the key doesn't have any pending operation before calling this function, 
    301  * or otherwise the behaviour is undefined (either callback will be called 
    302  * later when the data is sent/received, or the callback will not be called, 
    303  * or even something else). 
     300 * the key doesn't have any pending operations before calling this function, 
     301 * by calling #pj_ioqueue_is_pending() for all previously submitted 
     302 * operations except asynchronous connect, and if necessary call 
     303 * #pj_ioqueue_post_completion() to cancel the pending operations. 
     304 * 
     305 * Note that asynchronous connect operation will automatically be  
     306 * cancelled during the unregistration. 
    304307 * 
    305308 * @param key       The key that was previously obtained from registration. 
    306309 * 
    307310 * @return          PJ_SUCCESS on success or the error code. 
     311 * 
     312 * @see pj_ioqueue_is_pending 
    308313 */ 
    309314PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key ); 
     
    334339                                               void *user_data, 
    335340                                               void **old_data); 
     341 
     342 
     343/** 
     344 * Check if operation is pending on the specified operation key. 
     345 * The \c op_key must have been submitted as pending operation before, 
     346 * or otherwise the result is undefined. 
     347 * 
     348 * @param key       The key. 
     349 * @param op_key    The operation key, previously submitted to any of 
     350 *                  the I/O functions and has returned PJ_EPENDING. 
     351 * 
     352 * @return          Non-zero if operation is still pending. 
     353 */ 
     354PJ_DECL(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key, 
     355                                          pj_ioqueue_op_key_t *op_key ); 
     356 
     357 
     358/** 
     359 * Post completion status to the specified operation key and call the 
     360 * appropriate callback. When the callback is called, the number of bytes  
     361 * received in read/write callback or the status in accept/connect callback 
     362 * will be set from the \c bytes_status parameter. 
     363 * 
     364 * @param key           The key. 
     365 * @param op_key        Pending operation key. 
     366 * @param bytes_status  Number of bytes or status to be set. A good value 
     367 *                      to put here is -PJ_ECANCELLED. 
     368 * 
     369 * @return              PJ_SUCCESS if completion status has been successfully 
     370 *                      sent. 
     371 */ 
     372PJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key, 
     373                                                 pj_ioqueue_op_key_t *op_key, 
     374                                                 pj_ssize_t bytes_status ); 
     375 
    336376 
    337377 
  • pjproject/main/pjlib/include/pj/os.h

    r5 r36  
    326326 
    327327/** 
     328 * Increment the value of an atomic type and get the result. 
     329 * 
     330 * @param atomic_var    the atomic variable. 
     331 * 
     332 * @return              The incremented value. 
     333 */ 
     334PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var); 
     335 
     336/** 
    328337 * Decrement the value of an atomic type. 
    329338 * 
     
    331340 */ 
    332341PJ_DECL(void) pj_atomic_dec(pj_atomic_t *atomic_var); 
     342 
     343/** 
     344 * Decrement the value of an atomic type and get the result. 
     345 * 
     346 * @param atomic_var    the atomic variable. 
     347 * 
     348 * @return              The decremented value. 
     349 */ 
     350PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var); 
    333351 
    334352/** 
     
    340358PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var, 
    341359                             pj_atomic_value_t value); 
     360 
     361/** 
     362 * Add a value to an atomic type and get the result. 
     363 * 
     364 * @param atomic_var    The atomic variable. 
     365 * @param value         Value to be added. 
     366 * 
     367 * @return              The result after the addition. 
     368 */ 
     369PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var, 
     370                                                  pj_atomic_value_t value); 
    342371 
    343372/** 
  • pjproject/main/pjlib/include/pj/timer.h

    r4 r36  
    111111 
    112112/** 
    113  * Default flag for timer heap, indicates that synchronization will be 
    114  * used. 
    115  */ 
    116 #define PJ_TIMER_HEAP_SYNCHRONIZE       (0) 
    117  
    118 /** 
    119  * Flag to indicate that thread synchronization is NOT needed for the  
    120  * timer heap. 
    121  */ 
    122 #define PJ_TIMER_HEAP_NO_SYNCHRONIZE    (1) 
    123  
    124 /** 
    125113 * Calculate memory size required to create a timer heap. 
    126114 * 
     
    141129 *                  initially. If the application registers more entries  
    142130 *                  during runtime, then the timer heap will resize. 
    143  * @param flag      Creation flag, currently only PJ_TIMER_HEAP_NO_SYNCHRONIZE 
    144  *                  is recognized.. 
    145131 * @param ht        Pointer to receive the created timer heap. 
    146132 * 
     
    149135PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool, 
    150136                                           pj_size_t count, 
    151                                            unsigned flag, 
    152137                                           pj_timer_heap_t **ht); 
     138 
     139/** 
     140 * Destroy the timer heap. 
     141 * 
     142 * @param ht        The timer heap. 
     143 */ 
     144PJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht ); 
     145 
     146 
     147/** 
     148 * Set lock object to be used by the timer heap. By default, the timer heap 
     149 * uses dummy synchronization. 
     150 * 
     151 * @param ht        The timer heap. 
     152 * @param lock      The lock object to be used for synchronization. 
     153 * @param auto_del  If nonzero, the lock object will be destroyed when 
     154 *                  the timer heap is destroyed. 
     155 */ 
     156PJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht, 
     157                                      pj_lock_t *lock, 
     158                                      pj_bool_t auto_del ); 
     159 
     160/** 
     161 * Set maximum number of timed out entries to process in a single poll. 
     162 * 
     163 * @param ht        The timer heap. 
     164 * @param count     Number of entries. 
     165 * 
     166 * @return          The old number. 
     167 */ 
     168PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht, 
     169                                                           unsigned count ); 
    153170 
    154171/** 
     
    216233 */ 
    217234PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht,  
    218                                            pj_time_val *timeval); 
     235                                                  pj_time_val *timeval); 
    219236 
    220237/** 
     
    222239 * each of the expired timers. 
    223240 * 
    224  * @param ht        The timer heap. 
     241 * @param ht         The timer heap. 
    225242 * @param next_delay If this parameter is not NULL, it will be filled up with 
    226243 *                   the time delay until the next timer elapsed, or -1 in 
    227244 *                   the sec part if no entry exist. 
    228  * @return          The number of timers expired. 
    229  */ 
    230 PJ_DECL(int) pj_timer_heap_poll( pj_timer_heap_t *ht, pj_time_val *next_delay); 
     245 * 
     246 * @return           The number of timers expired. 
     247 */ 
     248PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht,  
     249                                      pj_time_val *next_delay); 
    231250 
    232251/** 
  • pjproject/main/pjlib/src/pj/errno.c

    r6 r36  
    3030    { PJ_EBUSY,         "Object is busy"}, 
    3131    { PJ_ENOTSUP,       "Option/operation is not supported"}, 
    32     { PJ_EINVALIDOP,    "Invalid operation"} 
     32    { PJ_EINVALIDOP,    "Invalid operation"}, 
     33    { PJ_ECANCELLED,    "Operation cancelled"} 
    3334}; 
    3435 
  • pjproject/main/pjlib/src/pj/file_io_ansi.c

    r18 r36  
    6868    written = fwrite(data, 1, *size, (FILE*)fd); 
    6969    if (ferror((FILE*)fd)) { 
     70        *size = -1; 
    7071        return PJ_RETURN_OS_ERROR(errno); 
    7172    } 
     
    8485    bytes = fread(data, 1, *size, (FILE*)fd); 
    8586    if (ferror((FILE*)fd)) { 
     87        *size = -1; 
    8688        return PJ_RETURN_OS_ERROR(errno); 
    8789    } 
  • pjproject/main/pjlib/src/pj/ioqueue_common_abs.c

    r35 r36  
    229229        if (h->fd_type == PJ_SOCK_DGRAM) { 
    230230            pj_list_erase(write_op); 
     231            write_op->op = 0; 
     232 
    231233            if (pj_list_empty(&h->write_list)) 
    232234                ioqueue_remove_from_set(ioqueue, h->fd, WRITEABLE_EVENT); 
     
    269271                /* Write completion of the whole stream. */ 
    270272                pj_list_erase(write_op); 
     273                write_op->op = 0; 
    271274 
    272275                /* Clear operation if there's no more data to send. */ 
     
    315318        accept_op = h->accept_list.next; 
    316319        pj_list_erase(accept_op); 
     320        accept_op->op = 0; 
    317321 
    318322        /* Clear bit in fdset if there is no more pending accept */ 
     
    348352        read_op = h->read_list.next; 
    349353        pj_list_erase(read_op); 
     354        read_op->op = 0; 
    350355 
    351356        /* Clear fdset if there is no pending read. */ 
     
    477482    PJ_CHECK_STACK(); 
    478483 
     484    read_op = (struct read_operation*)op_key; 
     485    read_op->op = 0; 
     486 
    479487    /* Try to see if there's data immediately available.  
    480488     */ 
     
    497505     * Must schedule asynchronous operation to the ioqueue. 
    498506     */ 
    499     read_op = (struct read_operation*)op_key; 
    500  
    501507    read_op->op = PJ_IOQUEUE_OP_RECV; 
    502508    read_op->buf = buffer; 
     
    531537    PJ_ASSERT_RETURN(key && op_key && buffer && length, PJ_EINVAL); 
    532538    PJ_CHECK_STACK(); 
     539 
     540    read_op = (struct read_operation*)op_key; 
     541    read_op->op = 0; 
    533542 
    534543    /* Try to see if there's data immediately available.  
     
    553562     * Must schedule asynchronous operation to the ioqueue. 
    554563     */ 
    555     read_op = (struct read_operation*)op_key; 
    556  
    557564    read_op->op = PJ_IOQUEUE_OP_RECV_FROM; 
    558565    read_op->buf = buffer; 
     
    587594    PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL); 
    588595    PJ_CHECK_STACK(); 
     596 
     597    write_op = (struct write_operation*)op_key; 
     598    write_op->op = 0; 
    589599 
    590600    /* Fast track: 
     
    625635     * Schedule asynchronous send. 
    626636     */ 
    627     write_op = (struct write_operation*)op_key; 
    628637    write_op->op = PJ_IOQUEUE_OP_SEND; 
    629638    write_op->buf = (void*)data; 
     
    660669    PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL); 
    661670    PJ_CHECK_STACK(); 
     671 
     672    write_op = (struct write_operation*)op_key; 
     673    write_op->op = 0; 
    662674 
    663675    /* Fast track: 
     
    703715     * Schedule asynchronous send. 
    704716     */ 
    705     write_op = (struct write_operation*)op_key; 
    706717    write_op->op = PJ_IOQUEUE_OP_SEND_TO; 
    707718    write_op->buf = (void*)data; 
     
    736747    /* check parameters. All must be specified! */ 
    737748    PJ_ASSERT_RETURN(key && op_key && new_sock, PJ_EINVAL); 
     749 
     750    accept_op = (struct accept_operation*)op_key; 
     751    accept_op->op = 0; 
    738752 
    739753    /* Fast track: 
     
    768782     * connection available. 
    769783     */ 
    770     accept_op = (struct accept_operation*)op_key; 
    771  
    772784    accept_op->op = PJ_IOQUEUE_OP_ACCEPT; 
    773785    accept_op->accept_fd = new_sock; 
     
    822834#endif  /* PJ_HAS_TCP */ 
    823835 
     836/* 
     837 * pj_ioqueue_is_pending() 
     838 */ 
     839PJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key, 
     840                                         pj_ioqueue_op_key_t *op_key ) 
     841{ 
     842    struct generic_operation *op_rec; 
     843 
     844    PJ_UNUSED_ARG(key); 
     845 
     846    op_rec = (struct generic_operation*)op_key; 
     847    return op_rec->op != 0; 
     848} 
     849 
     850 
     851/* 
     852 * pj_ioqueue_post_completion() 
     853 */ 
     854PJ_DEF(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key, 
     855                                                pj_ioqueue_op_key_t *op_key, 
     856                                                pj_ssize_t bytes_status ) 
     857{ 
     858    struct generic_operation *op_rec; 
     859 
     860    /* 
     861     * Find the operation key in all pending operation list to 
     862     * really make sure that it's still there; then call the callback. 
     863     */ 
     864    pj_mutex_lock(key->mutex); 
     865 
     866    /* Find the operation in the pending read list. */ 
     867    op_rec = (struct generic_operation*)key->read_list.next; 
     868    while (op_rec != (void*)&key->read_list) { 
     869        if (op_rec == (void*)op_key) { 
     870            pj_list_erase(op_rec); 
     871            op_rec->op = 0; 
     872            pj_mutex_unlock(key->mutex); 
     873 
     874            (*key->cb.on_read_complete)(key, op_key, bytes_status); 
     875            return PJ_SUCCESS; 
     876        } 
     877        op_rec = op_rec->next; 
     878    } 
     879 
     880    /* Find the operation in the pending write list. */ 
     881    op_rec = (struct generic_operation*)key->write_list.next; 
     882    while (op_rec != (void*)&key->write_list) { 
     883        if (op_rec == (void*)op_key) { 
     884            pj_list_erase(op_rec); 
     885            op_rec->op = 0; 
     886            pj_mutex_unlock(key->mutex); 
     887 
     888            (*key->cb.on_write_complete)(key, op_key, bytes_status); 
     889            return PJ_SUCCESS; 
     890        } 
     891        op_rec = op_rec->next; 
     892    } 
     893 
     894    /* Find the operation in the pending accept list. */ 
     895    op_rec = (struct generic_operation*)key->accept_list.next; 
     896    while (op_rec != (void*)&key->accept_list) { 
     897        if (op_rec == (void*)op_key) { 
     898            pj_list_erase(op_rec); 
     899            op_rec->op = 0; 
     900            pj_mutex_unlock(key->mutex); 
     901 
     902            (*key->cb.on_accept_complete)(key, op_key,  
     903                                          PJ_INVALID_SOCKET, 
     904                                          bytes_status); 
     905            return PJ_SUCCESS; 
     906        } 
     907        op_rec = op_rec->next; 
     908    } 
     909 
     910    pj_mutex_unlock(key->mutex); 
     911     
     912    return PJ_EINVALIDOP; 
     913} 
     914 
  • pjproject/main/pjlib/src/pj/ioqueue_winnt.c

    r19 r36  
    892892#endif  /* #if PJ_HAS_TCP */ 
    893893 
     894 
     895 
     896PJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key, 
     897                                         pj_ioqueue_op_key_t *op_key ) 
     898{ 
     899    BOOL rc; 
     900    DWORD bytesTransfered; 
     901 
     902    rc = GetOverlappedResult( key->hnd, (LPOVERLAPPED)op_key, 
     903                              &bytesTransfered, FALSE ); 
     904 
     905    if (rc == FALSE) { 
     906        return GetLastError()==ERROR_IO_INCOMPLETE; 
     907    } 
     908 
     909    return FALSE; 
     910} 
     911 
     912 
     913PJ_DEF(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key, 
     914                                                pj_ioqueue_op_key_t *op_key, 
     915                                                pj_ssize_t bytes_status ) 
     916{ 
     917    BOOL rc; 
     918 
     919    rc = PostQueuedCompletionStatus(key->ioqueue->iocp, bytes_status, 
     920                                    (long)key, (OVERLAPPED*)op_key ); 
     921    if (rc == FALSE) { 
     922        return PJ_RETURN_OS_ERROR(GetLastError()); 
     923    } 
     924 
     925    return PJ_SUCCESS; 
     926} 
     927 
  • pjproject/main/pjlib/src/pj/os_core_unix.c

    r35 r36  
    560560 
    561561/* 
     562 * pj_atomic_inc_and_get() 
     563 */ 
     564PJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var) 
     565{ 
     566    pj_atomic_value_t new_value; 
     567 
     568    PJ_CHECK_STACK(); 
     569 
     570#if PJ_HAS_THREADS 
     571    pj_mutex_lock( atomic_var->mutex ); 
     572#endif 
     573    new_value = ++atomic_var->value; 
     574#if PJ_HAS_THREADS 
     575    pj_mutex_unlock( atomic_var->mutex); 
     576#endif 
     577 
     578    return new_value; 
     579} 
     580/* 
    562581 * pj_atomic_inc() 
    563582 */ 
    564583PJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var) 
    565584{ 
     585    pj_atomic_inc_and_get(atomic_var); 
     586} 
     587 
     588/* 
     589 * pj_atomic_dec_and_get() 
     590 */ 
     591PJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var) 
     592{ 
     593    pj_atomic_value_t new_value; 
     594 
    566595    PJ_CHECK_STACK(); 
    567596 
     
    569598    pj_mutex_lock( atomic_var->mutex ); 
    570599#endif 
    571     ++atomic_var->value; 
     600    new_value = --atomic_var->value; 
    572601#if PJ_HAS_THREADS 
    573602    pj_mutex_unlock( atomic_var->mutex); 
    574603#endif 
     604 
     605    return new_value; 
    575606} 
    576607 
     
    580611PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var) 
    581612{ 
    582     PJ_CHECK_STACK(); 
    583  
    584 #if PJ_HAS_THREADS 
    585     pj_mutex_lock( atomic_var->mutex ); 
    586 #endif 
    587     --atomic_var->value; 
    588 #if PJ_HAS_THREADS 
    589     pj_mutex_unlock( atomic_var->mutex); 
    590 #endif 
     613    pj_atomic_dec_and_get(atomic_var); 
     614} 
     615 
     616/* 
     617 * pj_atomic_add_and_get() 
     618 */  
     619PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,  
     620                                                 pj_atomic_value_t value ) 
     621{ 
     622    pj_atomic_value_t new_value; 
     623 
     624#if PJ_HAS_THREADS 
     625    pj_mutex_lock(atomic_var->mutex); 
     626#endif 
     627     
     628    atomic_var->value += value; 
     629    new_value = atomic_var->value; 
     630 
     631#if PJ_HAS_THREADS 
     632    pj_mutex_unlock(atomic_var->mutex); 
     633#endif 
     634 
     635    return new_value; 
    591636} 
    592637 
     
    594639 * pj_atomic_add() 
    595640 */  
    596 PJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var, pj_atomic_value_t value ) 
    597 { 
    598 #if PJ_HAS_THREADS 
    599     pj_mutex_lock(atomic_var->mutex); 
    600 #endif 
    601      
    602     atomic_var->value += value; 
    603  
    604 #if PJ_HAS_THREADS 
    605     pj_mutex_unlock(atomic_var->mutex); 
    606 #endif 
    607 } 
    608  
     641PJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,  
     642                            pj_atomic_value_t value ) 
     643{ 
     644    pj_atomic_add_and_get(atomic_var, value); 
     645} 
    609646 
    610647/////////////////////////////////////////////////////////////////////////////// 
  • pjproject/main/pjlib/src/pj/os_core_win32.c

    r6 r36  
    514514 
    515515/* 
    516  * pj_atomic_inc() 
    517  */ 
    518 PJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var) 
     516 * pj_atomic_inc_and_get() 
     517 */ 
     518PJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var) 
    519519{ 
    520520    PJ_CHECK_STACK(); 
    521521 
    522522#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 
    523     InterlockedIncrement(&atomic_var->value); 
     523    return InterlockedIncrement(&atomic_var->value); 
    524524#else 
    525525#   error Fix Me 
     
    528528 
    529529/* 
    530  * pj_atomic_dec() 
    531  */ 
    532 PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var) 
     530 * pj_atomic_inc() 
     531 */ 
     532PJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var) 
     533{ 
     534    pj_atomic_inc_and_get(atomic_var); 
     535} 
     536 
     537/* 
     538 * pj_atomic_dec_and_get() 
     539 */ 
     540PJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var) 
    533541{ 
    534542    PJ_CHECK_STACK(); 
    535543 
    536544#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 
    537     InterlockedDecrement(&atomic_var->value); 
     545    return InterlockedDecrement(&atomic_var->value); 
    538546#else 
    539547#   error Fix me 
     
    542550 
    543551/* 
     552 * pj_atomic_dec() 
     553 */ 
     554PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var) 
     555{ 
     556    pj_atomic_dec_and_get(atomic_var); 
     557} 
     558 
     559/* 
    544560 * pj_atomic_add() 
    545561 */ 
     
    547563                            pj_atomic_value_t value ) 
    548564{ 
     565#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 
    549566    InterlockedExchangeAdd( &atomic_var->value, value ); 
    550 } 
    551  
    552          
     567#else 
     568#   error Fix me 
     569#endif 
     570} 
     571 
     572/* 
     573 * pj_atomic_add_and_get() 
     574 */ 
     575PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var, 
     576                                                 pj_atomic_value_t value) 
     577{ 
     578#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 
     579    long oldValue = InterlockedExchangeAdd( &atomic_var->value, value); 
     580    return oldValue + value; 
     581#else 
     582#   error Fix me 
     583#endif 
     584} 
     585 
    553586/////////////////////////////////////////////////////////////////////////////// 
    554587/* 
  • pjproject/main/pjlib/src/pj/timer.c

    r6 r36  
    1515#include <pj/assert.h> 
    1616#include <pj/errno.h> 
     17#include <pj/lock.h> 
    1718 
    1819#define HEAP_PARENT(X)  (X == 0 ? 0 : (((X) - 1) / 2)) 
    1920#define HEAP_LEFT(X)    (((X)+(X))+1) 
     21 
     22 
     23#define DEFAULT_MAX_TIMED_OUT_PER_POLL  (64) 
    2024 
    2125 
     
    3438    pj_size_t cur_size; 
    3539 
    36     /** Mutex for synchronization, or NULL */ 
    37     pj_mutex_t *mutex; 
     40    /** Max timed out entries to process per poll. */ 
     41    unsigned max_entries_per_poll; 
     42 
     43    /** Lock object. */ 
     44    pj_lock_t *lock; 
     45 
     46    /** Autodelete lock. */ 
     47    pj_bool_t auto_delete_lock; 
    3848 
    3949    /** 
     
    7282PJ_INLINE(void) lock_timer_heap( pj_timer_heap_t *ht ) 
    7383{ 
    74     if (ht->mutex) { 
    75         pj_mutex_lock(ht->mutex); 
     84    if (ht->lock) { 
     85        pj_lock_acquire(ht->lock); 
    7686    } 
    7787} 
     
    7989PJ_INLINE(void) unlock_timer_heap( pj_timer_heap_t *ht ) 
    8090{ 
    81     if (ht->mutex) { 
    82         pj_mutex_unlock(ht->mutex); 
     91    if (ht->lock) { 
     92        pj_lock_release(ht->lock); 
    8393    } 
    8494} 
     
    320330           /* size of each entry: */ 
    321331           (count+2) * (sizeof(pj_timer_entry*)+sizeof(pj_timer_id_t)) + 
    322            /* mutex, pool etc: */ 
     332           /* lock, pool etc: */ 
    323333           132; 
    324334} 
     
    329339PJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool, 
    330340                                          pj_size_t size, 
    331                                           unsigned flag, 
    332341                                          pj_timer_heap_t **p_heap) 
    333342{ 
     
    350359    ht->max_size = size; 
    351360    ht->cur_size = 0; 
     361    ht->max_entries_per_poll = DEFAULT_MAX_TIMED_OUT_PER_POLL; 
    352362    ht->timer_ids_freelist = 1; 
    353363    ht->pool = pool; 
    354364 
    355     /* Mutex. */ 
    356     if (flag & PJ_TIMER_HEAP_NO_SYNCHRONIZE) { 
    357         ht->mutex = NULL; 
    358     } else { 
    359         pj_status_t rc; 
    360  
    361         /* Mutex must be the recursive types.  
    362          * See commented code inside pj_timer_heap_poll()  
    363          */ 
    364         rc = pj_mutex_create(pool, "tmhp%p", PJ_MUTEX_RECURSE, &ht->mutex); 
    365         if (rc != PJ_SUCCESS) 
    366             return rc; 
    367     } 
     365    /* Lock. */ 
     366    ht->lock = NULL; 
     367    ht->auto_delete_lock = 0; 
    368368 
    369369    // Create the heap array. 
     
    387387} 
    388388 
     389PJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht ) 
     390{ 
     391    if (ht->lock && ht->auto_delete_lock) { 
     392        pj_lock_destroy(ht->lock); 
     393        ht->lock = NULL; 
     394    } 
     395} 
     396 
     397PJ_DEF(void) pj_timer_heap_set_lock(  pj_timer_heap_t *ht, 
     398                                      pj_lock_t *lock, 
     399                                      pj_bool_t auto_del ) 
     400{ 
     401    if (ht->lock && ht->auto_delete_lock) 
     402        pj_lock_destroy(ht->lock); 
     403 
     404    ht->lock = lock; 
     405    ht->auto_delete_lock = auto_del; 
     406} 
     407 
     408 
     409PJ_DEF(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht, 
     410                                                          unsigned count ) 
     411{ 
     412    unsigned old_count = ht->max_entries_per_poll; 
     413    ht->max_entries_per_poll = count; 
     414    return old_count; 
     415} 
     416 
    389417PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry, 
    390418                                             int id, 
     
    434462} 
    435463 
    436 PJ_DEF(int) pj_timer_heap_poll( pj_timer_heap_t *ht, pj_time_val *next_delay ) 
     464PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht,  
     465                                     pj_time_val *next_delay ) 
    437466{ 
    438467    pj_time_val now; 
    439     int count; 
    440  
    441     PJ_ASSERT_RETURN(ht, -1); 
     468    unsigned count; 
     469 
     470    PJ_ASSERT_RETURN(ht, 0); 
    442471 
    443472    if (!ht->cur_size && next_delay) { 
     
    451480    lock_timer_heap(ht); 
    452481    while ( ht->cur_size &&  
    453             PJ_TIME_VAL_LTE(ht->heap[0]->_timer_value, now) )  
     482            PJ_TIME_VAL_LTE(ht->heap[0]->_timer_value, now) && 
     483            count < ht->max_entries_per_poll )  
    454484    { 
    455485        pj_timer_entry *node = remove_node(ht, 0); 
    456486        ++count; 
    457487 
    458         //Better not to temporarily release mutex to save some syscalls. 
    459         //But then make sure the mutex must be the recursive types (PJ_MUTEX_RECURSE)! 
    460         //unlock_timer_heap(ht); 
     488        unlock_timer_heap(ht); 
    461489        (*node->cb)(ht, node); 
    462         //lock_timer_heap(ht); 
     490        lock_timer_heap(ht); 
    463491    } 
    464492    if (ht->cur_size && next_delay) { 
     
    475503PJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht ) 
    476504{ 
     505    PJ_ASSERT_RETURN(ht, 0); 
     506 
    477507    return ht->cur_size; 
    478508} 
Note: See TracChangeset for help on using the changeset viewer.