- Timestamp:
- Nov 9, 2005 3:37:19 PM (19 years ago)
- 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="pjlib pp" - Package Owner=<4>1 # Microsoft Developer Studio Project File - Name="pjlib++" - Package Owner=<4> 2 2 # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 3 # ** DO NOT EDIT ** … … 5 5 # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 6 7 CFG=pjlib pp- Win32 Debug7 CFG=pjlib++ - Win32 Debug 8 8 !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 9 !MESSAGE use the Export Makefile command and run 10 10 !MESSAGE 11 !MESSAGE NMAKE /f "pjlib pp.mak".11 !MESSAGE NMAKE /f "pjlib++.mak". 12 12 !MESSAGE 13 13 !MESSAGE You can specify a configuration when running NMAKE 14 14 !MESSAGE by defining the macro CFG on the command line. For example: 15 15 !MESSAGE 16 !MESSAGE NMAKE /f "pjlib pp.mak" CFG="pjlibpp- Win32 Debug"16 !MESSAGE NMAKE /f "pjlib++.mak" CFG="pjlib++ - Win32 Debug" 17 17 !MESSAGE 18 18 !MESSAGE Possible choices for configuration are: 19 19 !MESSAGE 20 !MESSAGE "pjlib pp- Win32 Release" (based on "Win32 (x86) Static Library")21 !MESSAGE "pjlib pp- 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") 22 22 !MESSAGE 23 23 … … 29 29 RSC=rc.exe 30 30 31 !IF "$(CFG)" == "pjlib pp- Win32 Release"31 !IF "$(CFG)" == "pjlib++ - Win32 Release" 32 32 33 33 # PROP BASE Use_MFC 0 34 34 # PROP BASE Use_Debug_Libraries 0 35 # PROP BASE Output_Dir ".\output\pjlib pp-i386-win32-vc6-release"36 # PROP BASE Intermediate_Dir ".\output\pjlib pp-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" 37 37 # PROP BASE Target_Dir "" 38 38 # PROP Use_MFC 0 39 39 # PROP Use_Debug_Libraries 0 40 # PROP Output_Dir ".\output\pjlib pp-i386-win32-vc6-release"41 # PROP Intermediate_Dir ".\output\pjlib pp-i386-win32-vc6-release"40 # PROP Output_Dir ".\output\pjlib++-i386-win32-vc6-release" 41 # PROP Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-release" 42 42 # PROP Target_Dir "" 43 43 # 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 /c44 # 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 45 45 # SUBTRACT CPP /YX 46 46 # ADD BASE RSC /l 0x409 /d "NDEBUG" … … 53 53 # ADD LIB32 /nologo /out:"../lib/pjlibp_vc6s.lib" 54 54 55 !ELSEIF "$(CFG)" == "pjlib pp- Win32 Debug"55 !ELSEIF "$(CFG)" == "pjlib++ - Win32 Debug" 56 56 57 57 # PROP BASE Use_MFC 0 58 58 # PROP BASE Use_Debug_Libraries 1 59 # PROP BASE Output_Dir ".\output\pjlib pp-i386-win32-vc6-debug"60 # PROP BASE Intermediate_Dir ".\output\pjlib pp-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" 61 61 # PROP BASE Target_Dir "" 62 62 # PROP Use_MFC 0 63 63 # PROP Use_Debug_Libraries 1 64 # PROP Output_Dir ".\output\pjlib pp-i386-win32-vc6-debug"65 # PROP Intermediate_Dir ".\output\pjlib pp-i386-win32-vc6-debug"64 # PROP Output_Dir ".\output\pjlib++-i386-win32-vc6-debug" 65 # PROP Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-debug" 66 66 # PROP Target_Dir "" 67 67 # 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 /c68 # 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 69 69 # SUBTRACT CPP /YX 70 70 # ADD BASE RSC /l 0x409 /d "_DEBUG" … … 81 81 # Begin Target 82 82 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" 101 85 # Begin Group "Header Files" 102 86 … … 104 88 # Begin Source File 105 89 106 SOURCE="..\ src\pj++\hash.hpp"90 SOURCE="..\include\pj++\file.hpp" 107 91 # End Source File 108 92 # Begin Source File 109 93 110 SOURCE="..\ src\pj++\ioqueue.hpp"94 SOURCE="..\include\pj++\hash.hpp" 111 95 # End Source File 112 96 # Begin Source File 113 97 114 SOURCE="..\ src\pj++\list.hpp"98 SOURCE="..\include\pj++\list.hpp" 115 99 # End Source File 116 100 # Begin Source File 117 101 118 SOURCE="..\ src\pj++\os.hpp"102 SOURCE="..\include\pj++\lock.hpp" 119 103 # End Source File 120 104 # Begin Source File 121 105 122 SOURCE="..\ src\pjlib++.hpp"106 SOURCE="..\include\pj++\os.hpp" 123 107 # End Source File 124 108 # Begin Source File 125 109 126 SOURCE="..\ src\pj++\pool.hpp"110 SOURCE="..\include\pj++\pool.hpp" 127 111 # End Source File 128 112 # Begin Source File 129 113 130 SOURCE="..\ src\pj++\proactor.hpp"114 SOURCE="..\include\pj++\proactor.hpp" 131 115 # End Source File 132 116 # Begin Source File 133 117 134 SOURCE="..\ src\pj++\scanner.hpp"118 SOURCE="..\include\pj++\scanner.hpp" 135 119 # End Source File 136 120 # Begin Source File 137 121 138 SOURCE="..\ src\pj++\sock.hpp"122 SOURCE="..\include\pj++\sock.hpp" 139 123 # End Source File 140 124 # Begin Source File 141 125 142 SOURCE="..\ src\pj++\string.hpp"126 SOURCE="..\include\pj++\string.hpp" 143 127 # End Source File 144 128 # Begin Source File 145 129 146 SOURCE="..\ src\pj++\timer.hpp"130 SOURCE="..\include\pj++\timer.hpp" 147 131 # End Source File 148 132 # Begin Source File 149 133 150 SOURCE="..\ src\pj++\tree.hpp"134 SOURCE="..\include\pj++\tree.hpp" 151 135 # End Source File 152 136 # Begin Source File 153 137 154 SOURCE="..\ src\pj++\types.hpp"138 SOURCE="..\include\pj++\types.hpp" 155 139 # End Source File 156 140 # End Group -
pjproject/main/pjlib/build/pjlib.dsp
r32 r36 235 235 236 236 SOURCE=..\src\pj\ioqueue_winnt.c 237 238 !IF "$(CFG)" == "pjlib - Win32 Release" 239 240 !ELSEIF "$(CFG)" == "pjlib - Win32 Debug" 241 242 !ENDIF 243 237 244 # End Source File 238 245 # Begin Source File -
pjproject/main/pjlib/build/pjlib.dsw
r1 r36 4 4 ############################################################################### 5 5 6 Project: "pjlib"= ".\pjlib.dsp"- Package Owner=<4>6 Project: "pjlib"=.\pjlib.dsp - Package Owner=<4> 7 7 8 8 Package=<5> 9 9 {{{ 10 begin source code control11 "$/pjproject-0.3/pjlib/build", EJDAAAAA12 .13 end source code control14 10 }}} 15 11 … … 20 16 ############################################################################### 21 17 22 Project: "pjlib _samples"=".\pjlib_samples.dsp" - Package Owner=<4>18 Project: "pjlib++"=".\pjlib++.dsp" - Package Owner=<4> 23 19 24 20 Package=<5> 25 21 {{{ 26 begin source code control 27 "$/pjproject-0.3/pjlib/build", EJDAAAAA 28 . 29 end source code control 22 }}} 23 24 Package=<4> 25 {{{ 26 }}} 27 28 ############################################################################### 29 30 Project: "pjlib_samples"=.\pjlib_samples.dsp - Package Owner=<4> 31 32 Package=<5> 33 {{{ 30 34 }}} 31 35 … … 39 43 ############################################################################### 40 44 41 Project: "pjlib_test"= ".\pjlib_test.dsp"- Package Owner=<4>45 Project: "pjlib_test"=.\pjlib_test.dsp - Package Owner=<4> 42 46 43 47 Package=<5> 44 48 {{{ 45 begin source code control46 "$/pjproject-0.3/pjlib/build", EJDAAAAA47 .48 end source code control49 49 }}} 50 50 … … 58 58 ############################################################################### 59 59 60 Project: "pjlib pp"=".\pjlibpp.dsp"- Package Owner=<4>60 Project: "pjlib++_test"=.\pjlib++-test.dsp - Package Owner=<4> 61 61 62 62 Package=<5> 63 63 {{{ 64 begin source code control65 "$/pjproject-0.3/pjlib/build", EJDAAAAA66 .67 end source code control68 64 }}} 69 65 70 66 Package=<4> 71 67 {{{ 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 72 74 }}} 73 75 … … 78 80 Package=<5> 79 81 {{{ 80 begin source code control81 "$/pjproject-0.3/pjlib/build", EJDAAAAA82 .83 end source code control84 82 }}} 85 83 -
pjproject/main/pjlib/include/pj++/hash.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_HASH_H__ … … 6 5 7 6 #include <pj++/types.hpp> 7 #include <pj++/pool.hpp> 8 8 #include <pj/hash.h> 9 9 10 class PJ_Hash_Table 10 // 11 // Hash table. 12 // 13 class Pj_Hash_Table : public Pj_Object 11 14 { 12 15 public: 16 // 17 // Hash table iterator. 18 // 13 19 class iterator 14 20 { 15 21 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 } 22 46 private: 23 47 pj_hash_table_t *ht_; … … 25 49 pj_hash_iterator_t *it_; 26 50 27 friend class P J_Hash_Table;51 friend class Pj_Hash_Table; 28 52 }; 29 53 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) 31 58 { 32 return (PJ_Hash_Table*)pj_hash_create(pool->pool_(), size);59 table_ = pj_hash_create(pool->pool_(), size); 33 60 } 34 61 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) 36 75 { 37 76 return pj_hash_calc(initial_hval, key, keylen); 38 77 } 39 78 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_() 41 83 { 42 return (pj_hash_table_t*)this;84 return table_; 43 85 } 44 86 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) 46 91 { 47 return pj_hash_get(t his->hash_table_(), key, keylen);92 return pj_hash_get(table_, key, keylen); 48 93 } 49 94 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) 51 103 { 52 pj_hash_set(pool->pool_(), t his->hash_table_(), key, keylen, value);104 pj_hash_set(pool->pool_(), table_, key, keylen, value); 53 105 } 54 106 107 // 108 // Get number of items in the hash table. 109 // 55 110 unsigned count() 56 111 { 57 return pj_hash_count(t his->hash_table_());112 return pj_hash_count(table_); 58 113 } 59 114 115 // 116 // Iterate hash table. 117 // 60 118 iterator begin() 61 119 { 62 iterator it(t his->hash_table_(), NULL);63 it.it_ = pj_hash_first(t his->hash_table_(), &it.it_val_);120 iterator it(table_, NULL); 121 it.it_ = pj_hash_first(table_, &it.it_val_); 64 122 return it; 65 123 } 66 124 125 // 126 // End of items. 127 // 67 128 iterator end() 68 129 { 69 return iterator(t his->hash_table_(), NULL);130 return iterator(table_, NULL); 70 131 } 132 133 private: 134 pj_hash_table_t *table_; 71 135 }; 72 136 137 73 138 #endif /* __PJPP_HASH_H__ */ 139 -
pjproject/main/pjlib/include/pj++/list.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_LIST_H__ … … 6 5 7 6 #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 // 24 template <class List_Node> 25 class Pj_List : public Pj_Object 18 26 { 19 27 public: 20 PJ_List() { pj_list_init(&root_); if (0) compiletest(); }21 ~PJ_List() {}22 28 // 29 // List const_iterator. 30 // 23 31 class const_iterator 24 32 { 25 33 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 } 33 60 34 61 protected: 35 Node *node_;62 List_Node *node_; 36 63 }; 37 64 65 // 66 // List iterator. 67 // 38 68 class iterator : public const_iterator 39 69 { 40 70 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 } 48 96 }; 49 97 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 // 50 110 bool empty() const 51 111 { … … 53 113 } 54 114 115 // 116 // Get first element. 117 // 55 118 iterator begin() 56 119 { … … 58 121 } 59 122 123 // 124 // Get first element. 125 // 60 126 const_iterator begin() const 61 127 { … … 63 129 } 64 130 131 // 132 // Get end-of-element 133 // 65 134 const_iterator end() const 66 135 { 67 return const_iterator((Node*)&root_); 68 } 69 136 return const_iterator((List_Node*)&root_); 137 } 138 139 // 140 // Get end-of-element 141 // 70 142 iterator end() 71 143 { 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) 76 151 { 77 152 pj_list_insert_before( *pos, node ); 78 153 } 79 154 80 void insert_after(iterator &pos, Node *node) 155 // 156 // Insert node. 157 // 158 void insert_after(iterator &pos, List_Node *node) 81 159 { 82 160 pj_list_insert_after(*pos, node); 83 161 } 84 162 85 void merge_first(Node *list2) 163 // 164 // Merge list. 165 // 166 void merge_first(List_Node *list2) 86 167 { 87 168 pj_list_merge_first(&root_, list2); 88 169 } 89 170 90 void merge_last(PJ_List *list) 171 // 172 // Merge list. 173 // 174 void merge_last(Pj_List *list) 91 175 { 92 176 pj_list_merge_last(&root_, &list->root_); 93 177 } 94 178 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) 96 183 { 97 184 pj_list_insert_nodes_before(*pos, &list2->root_); 98 185 } 99 186 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) 101 191 { 102 192 pj_list_insert_nodes_after(*pos, &list2->root_); 103 193 } 104 194 195 // 196 // Erase an element. 197 // 105 198 void erase(iterator &it) 106 199 { … … 108 201 } 109 202 110 Node *front() 203 // 204 // Get first element. 205 // 206 List_Node *front() 111 207 { 112 208 return root_.next; 113 209 } 114 210 115 const Node *front() const 211 // 212 // Get first element. 213 // 214 const List_Node *front() const 116 215 { 117 216 return root_.next; 118 217 } 119 218 219 // 220 // Remove first element. 221 // 120 222 void pop_front() 121 223 { … … 123 225 } 124 226 125 Node *back() 227 // 228 // Get last element. 229 // 230 List_Node *back() 126 231 { 127 232 return root_.prev; 128 233 } 129 234 130 const Node *back() const 235 // 236 // Get last element. 237 // 238 const List_Node *back() const 131 239 { 132 240 return root_.prev; 133 241 } 134 242 243 // 244 // Remove last element. 245 // 135 246 void pop_back() 136 247 { … … 138 249 } 139 250 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); 143 257 return n ? iterator(n) : end(); 144 258 } 145 259 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); 149 266 return n ? const_iterator(n) : end(); 150 267 } 151 268 152 void push_back(Node *node) 269 // 270 // Insert a node in the back. 271 // 272 void push_back(List_Node *node) 153 273 { 154 274 pj_list_insert_after(root_.prev, node); 155 275 } 156 276 157 void push_front(Node *node) 277 // 278 // Insert a node in the front. 279 // 280 void push_front(List_Node *node) 158 281 { 159 282 pj_list_insert_before(root_.next, node); 160 283 } 161 284 285 // 286 // Remove all elements. 287 // 162 288 void clear() 163 289 { … … 169 295 struct RootNode 170 296 { 171 PJ_DECL_LIST_MEMBER( Node)297 PJ_DECL_LIST_MEMBER(List_Node); 172 298 } root_; 173 299 … … 175 301 { 176 302 // 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; 179 305 n = n->next; n = n->prev; 180 306 } -
pjproject/main/pjlib/include/pj++/os.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_OS_H__ … … 9 8 #include <pj++/pool.hpp> 10 9 11 class PJ_Thread 10 class Pj_Thread; 11 12 // 13 // Thread API. 14 // 15 class Pj_Thread_API 16 { 17 public: 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 // 99 class Pj_Thread : public Pj_Object 12 100 { 13 101 public: … … 17 105 }; 18 106 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 // 47 144 pj_thread_t *pj_thread_t_() 48 145 { 49 return (pj_thread_t*)this; 50 } 51 146 return thread_; 147 } 148 149 // 150 // Get thread name. 151 // 52 152 const char *get_name() 53 153 { 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 // 57 160 pj_status_t resume() 58 161 { 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 // 62 168 pj_status_t join() 63 169 { 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 // 67 176 pj_status_t destroy() 68 177 { 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 184 protected: 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 // 204 class Pj_External_Thread : public Pj_Thread 205 { 206 public: 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 220 private: 221 pj_thread_desc desc_; 222 }; 223 224 225 // 226 // Thread specific data/thread local storage/TLS. 227 // 228 class Pj_Thread_Local_API 229 { 230 public: 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 // 272 class Pj_Atomic_Var : public Pj_Object 273 { 274 public: 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 // 112 323 pj_atomic_t *pj_atomic_t_() 113 324 { 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 392 private: 393 pj_atomic_t *var_; 394 }; 395 396 397 // 398 // Mutex 399 // 400 class Pj_Mutex : public Pj_Object 401 { 402 public: 403 // 404 // Mutex type. 405 // 147 406 enum Type 148 407 { … … 152 411 }; 153 412 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 500 private: 501 pj_mutex_t *mutex_; 502 }; 503 504 505 // 506 // Semaphore 507 // 508 class Pj_Semaphore : public Pj_Object 509 { 510 public: 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 // 201 552 pj_sem_t *pj_sem_t_() 202 553 { … … 204 555 } 205 556 206 pj_status_t destroy() 207 { 208 return pj_sem_destroy(this->pj_sem_t_()); 209 } 210 557 // 558 // Wait semaphore. 559 // 211 560 pj_status_t wait() 212 561 { … … 214 563 } 215 564 216 pj_status_t lock() 565 // 566 // Wait semaphore. 567 // 568 pj_status_t acquire() 217 569 { 218 570 return wait(); 219 571 } 220 572 573 // 574 // Try wait semaphore. 575 // 221 576 pj_status_t trywait() 222 577 { … … 224 579 } 225 580 226 pj_status_t trylock() 581 // 582 // Try wait semaphore. 583 // 584 pj_status_t tryacquire() 227 585 { 228 586 return trywait(); 229 587 } 230 588 589 // 590 // Post semaphore. 591 // 231 592 pj_status_t post() 232 593 { … … 234 595 } 235 596 236 pj_status_t unlock() 597 // 598 // Post semaphore. 599 // 600 pj_status_t release() 237 601 { 238 602 return post(); 239 603 } 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 605 private: 606 pj_sem_t *sem_; 607 }; 608 609 610 // 611 // Event object. 612 // 613 class Pj_Event 614 { 615 public: 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 // 251 648 pj_event_t *pj_event_t_() 252 649 { 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 // 261 667 pj_status_t wait() 262 668 { 263 return pj_event_wait(this->pj_event_t_()); 264 } 265 669 return pj_event_wait(event_); 670 } 671 672 // 673 // Try wait. 674 // 266 675 pj_status_t trywait() 267 676 { 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 // 271 683 pj_status_t set() 272 684 { … … 274 686 } 275 687 688 // 689 // Release one waiting thread. 690 // 276 691 pj_status_t pulse() 277 692 { … … 279 694 } 280 695 696 // 697 // Set a non-signalled. 698 // 281 699 pj_status_t reset() 282 700 { 283 701 return pj_event_reset(this->pj_event_t_()); 284 702 } 285 }; 286 287 class PJ_OS 288 { 289 public: 290 static pj_status_t gettimeofday( PJ_Time_Val *tv ) 703 704 private: 705 pj_event_t *event_; 706 }; 707 708 // 709 // OS abstraction. 710 // 711 class Pj_OS_API 712 { 713 public: 714 // 715 // Get current time. 716 // 717 static pj_status_t gettimeofday( Pj_Time_Val *tv ) 291 718 { 292 719 return pj_gettimeofday(tv); 293 720 } 294 721 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 ) 296 727 { 297 728 return pj_time_decode(tv, pt); 298 729 } 299 730 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) 301 736 { 302 737 return pj_time_encode(pt, tv); 303 738 } 304 739 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 ) 306 744 { 307 745 return pj_time_local_to_gmt( tv ); 308 746 } 309 747 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) 311 752 { 312 753 return pj_time_gmt_to_local( tv ); … … 314 755 }; 315 756 316 317 inline pj_status_t PJ_Time_Val::gettimeofday() 318 { 319 return PJ_OS::gettimeofday(this); 757 // 758 // Timeval inlines. 759 // 760 inline pj_status_t Pj_Time_Val::gettimeofday() 761 { 762 return Pj_OS_API::gettimeofday(this); 320 763 } 321 764 322 inline pj_parsed_time P J_Time_Val::decode()765 inline pj_parsed_time Pj_Time_Val::decode() 323 766 { 324 767 pj_parsed_time pt; 325 P J_OS::time_decode(this, &pt);768 Pj_OS_API::time_decode(this, &pt); 326 769 return pt; 327 770 } 328 771 329 inline pj_status_t P J_Time_Val::encode(const pj_parsed_time *pt)330 { 331 return P J_OS::time_encode(pt, this);772 inline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt) 773 { 774 return Pj_OS_API::time_encode(pt, this); 332 775 } 333 776 334 inline pj_status_t P J_Time_Val::to_gmt()335 { 336 return P J_OS::time_local_to_gmt(this);777 inline pj_status_t Pj_Time_Val::to_gmt() 778 { 779 return Pj_OS_API::time_local_to_gmt(this); 337 780 } 338 781 339 inline pj_status_t P J_Time_Val::to_local()340 { 341 return P J_OS::time_gmt_to_local(this);782 inline pj_status_t Pj_Time_Val::to_local() 783 { 784 return Pj_OS_API::time_gmt_to_local(this); 342 785 } 343 786 -
pjproject/main/pjlib/include/pj++/pool.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_POOL_H__ … … 7 6 #include <pj/pool.h> 8 7 9 class PJ_Pool 8 class Pj_Pool; 9 class Pj_Caching_Pool; 10 11 // 12 // Base class for all Pjlib objects 13 // 14 class Pj_Object 10 15 { 11 16 public: 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 25 private: 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 // 38 class Pj_Pool : public Pj_Object 39 { 40 public: 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 // 12 93 const char *getobjname() const 13 94 { 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 // 17 101 pj_pool_t *pool_() 18 102 { 19 return (pj_pool_t*)this; 20 } 21 103 return p_; 104 } 105 106 // 107 // Get pjlib compatible pool object. 108 // 22 109 const pj_pool_t *pool_() const 23 110 { 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 // 32 125 void reset() 33 126 { 34 pj_pool_reset(this->pool_()); 35 } 36 127 pj_pool_reset(p_); 128 } 129 130 // 131 // Get current capacity. 132 // 37 133 pj_size_t get_capacity() 38 134 { 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 // 42 141 pj_size_t get_used_size() 43 142 { 44 pj_pool_get_used_size(this->pool_()); 45 } 46 143 pj_pool_get_used_size(p_); 144 } 145 146 // 147 // Allocate. 148 // 47 149 void *alloc(pj_size_t size) 48 150 { 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 // 52 157 void *calloc(pj_size_t count, pj_size_t elem) 53 158 { 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 170 private: 171 pj_pool_t *p_; 56 172 }; 57 173 58 class PJ_Caching_Pool 174 175 // 176 // Caching pool. 177 // 178 class Pj_Caching_Pool 59 179 { 60 180 public: 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() 68 194 { 69 195 pj_caching_pool_destroy(&cp_); 70 196 } 71 197 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); 80 210 } 81 211 … … 84 214 }; 85 215 216 // 217 // Inlines for Pj_Object 218 // 219 inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool *pool) 220 { 221 return pool->alloc(class_size); 222 } 223 inline void Pj_Object::operator delete(void *ptr) 224 { 225 } 226 inline void Pj_Object::operator delete(void *ptr, Pj_Pool*) 227 { 228 } 229 230 // 231 // Inlines for Pj_Pool 232 // 233 inline 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 86 244 #endif /* __PJPP_POOL_H__ */ -
pjproject/main/pjlib/include/pj++/proactor.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 #ifndef __PJPP_ EVENT_HANDLER_H__5 #define __PJPP_ EVENT_HANDLER_H__3 #ifndef __PJPP_PROACTOR_H__ 4 #define __PJPP_PROACTOR_H__ 6 5 7 6 #include <pj/ioqueue.h> … … 9 8 #include <pj++/sock.hpp> 10 9 #include <pj++/timer.hpp> 11 12 class PJ_Proactor; 13 14 15 class PJ_Event_Handler 10 #include <pj/errno.h> 11 12 class Pj_Proactor; 13 class 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 // 22 class Pj_Async_Op : public pj_ioqueue_op_key_t 16 23 { 17 friend class PJ_Proactor;18 24 public: 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 44 protected: 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 // 57 class Pj_Event_Handler : public Pj_Object 58 { 59 friend class Pj_Proactor; 60 public: 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 28 143 #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 31 165 #endif 32 166 33 167 protected: 34 // 168 ////////////////// 35 169 // 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 40 195 #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 43 212 #endif 44 213 214 45 215 private: 46 PJ_Proactor *proactor_;47 216 pj_ioqueue_key_t *key_; 48 217 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 } 58 233 }; 59 234 60 class PJ_Proactor 235 inline bool Pj_Async_Op::is_pending() 236 { 237 return pj_ioqueue_is_pending(handler_->key_, this) != 0; 238 } 239 240 inline 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 // 249 class Pj_Proactor : public Pj_Object 61 250 { 62 251 public: 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 } 80 411 81 412 private: 82 413 pj_ioqueue_t *ioq_; 83 414 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 86 479 }; 87 480 88 #endif /* __PJPP_ EVENT_HANDLER_H__ */481 #endif /* __PJPP_PROACTOR_H__ */ -
pjproject/main/pjlib/include/pj++/scanner.hpp
r29 r36 5 5 #define __PJPP_SCANNER_H__ 6 6 7 #include <pj /scanner.h>7 #include <pjlib-util/scanner.h> 8 8 #include <pj++/string.hpp> 9 9 10 class P J_CharSpec10 class Pj_Char_Spec 11 11 { 12 12 public: 13 P J_CharSpec() { pj_cs_init(cs__); }13 Pj_Char_Spec() { pj_cs_init(cs__); } 14 14 15 15 void set(int c) { pj_cs_set(cs__, c); } … … 37 37 }; 38 38 39 class P J_Scanner39 class Pj_Scanner 40 40 { 41 41 public: 42 P J_Scanner() {}42 Pj_Scanner() {} 43 43 44 44 enum … … 68 68 int peek_char() const 69 69 { 70 return *scanner_.cur rent;70 return *scanner_.curptr; 71 71 } 72 72 73 int peek(const P J_CharSpec *cs, PJ_String *out)73 int peek(const Pj_Char_Spec *cs, Pj_String *out) 74 74 { 75 75 return pj_scan_peek(&scanner_, cs->cs_(), out); 76 76 } 77 77 78 int peek_n(pj_size_t len, P J_String *out)78 int peek_n(pj_size_t len, Pj_String *out) 79 79 { 80 80 return pj_scan_peek_n(&scanner_, len, out); 81 81 } 82 82 83 int peek_until(const P J_CharSpec *cs, PJ_String *out)83 int peek_until(const Pj_Char_Spec *cs, Pj_String *out) 84 84 { 85 85 return pj_scan_peek_until(&scanner_, cs->cs_(), out); 86 86 } 87 87 88 void get(const P J_CharSpec *cs, PJ_String *out)88 void get(const Pj_Char_Spec *cs, Pj_String *out) 89 89 { 90 90 pj_scan_get(&scanner_, cs->cs_(), out); 91 91 } 92 92 93 void get_n(unsigned N, P J_String *out)93 void get_n(unsigned N, Pj_String *out) 94 94 { 95 95 pj_scan_get_n(&scanner_, N, out); … … 101 101 } 102 102 103 void get_quote(int begin_quote, int end_quote, P J_String *out)103 void get_quote(int begin_quote, int end_quote, Pj_String *out) 104 104 { 105 105 pj_scan_get_quote(&scanner_, begin_quote, end_quote, out); … … 111 111 } 112 112 113 void get_until(const P J_CharSpec *cs, PJ_String *out)113 void get_until(const Pj_Char_Spec *cs, Pj_String *out) 114 114 { 115 115 pj_scan_get_until(&scanner_, cs->cs_(), out); 116 116 } 117 117 118 void get_until_ch(int until_ch, P J_String *out)118 void get_until_ch(int until_ch, Pj_String *out) 119 119 { 120 120 pj_scan_get_until_ch(&scanner_, until_ch, out); 121 121 } 122 122 123 void get_until_chr(const char *spec, P J_String *out)123 void get_until_chr(const char *spec, Pj_String *out) 124 124 { 125 125 pj_scan_get_until_chr(&scanner_, spec, out); -
pjproject/main/pjlib/include/pj++/sock.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_SOCK_H__ … … 6 5 7 6 #include <pj/sock.h> 8 9 class PJ_Addr 7 #include <pj/string.h> 8 9 class Pj_Event_Handler; 10 11 // 12 // Base class for address. 13 // 14 class Pj_Addr 10 15 { 11 16 }; 12 17 13 class PJ_INET_Addr : public pj_sockaddr_in, public PJ_Addr 18 // 19 // Internet address. 20 // 21 class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr 14 22 { 15 23 public: 24 // 25 // Get port number. 26 // 16 27 pj_uint16_t get_port_number() const 17 28 { 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 // 21 35 void set_port_number(pj_uint16_t port) 22 36 { 23 37 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 // 27 44 pj_uint32_t get_ip_address() const 28 45 { 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 // 32 52 const char *get_address() const 33 53 { 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 // 37 60 void set_ip_address(pj_uint32_t addr) 38 61 { 39 62 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 // 43 69 pj_status_t set_address(const pj_str_t *addr) 44 70 { 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 // 48 77 pj_status_t set_address(const char *addr) 49 78 { 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 93 private: 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_; 62 103 }; 63 104 64 class PJ_Socket 105 106 // 107 // Socket base class. 108 // 109 // Note: 110 // socket will not automatically be closed on destructor. 111 // 112 class Pj_Socket 65 113 { 66 114 public: 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 // 70 150 void set_handle(pj_sock_t sock) 71 151 { … … 73 153 } 74 154 155 // 156 // Get socket handle. 157 // 75 158 pj_sock_t get_handle() const 76 159 { … … 78 161 } 79 162 163 // 164 // Get socket handle. 165 // 80 166 pj_sock_t& get_handle() 81 167 { … … 83 169 } 84 170 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; 136 274 } 137 275 138 276 protected: 277 friend class Pj_Event_Handler; 139 278 pj_sock_t sock_; 140 279 }; 141 280 281 142 282 #if PJ_HAS_TCP 143 class PJ_Sock_Stream : public PJ_Socket 283 // 284 // Stream socket. 285 // 286 class Pj_Sock_Stream : public Pj_Socket 144 287 { 145 288 public: 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); 172 350 } 173 351 … … 175 353 #endif 176 354 177 class PJ_Sock_Dgram : public PJ_Socket 355 // 356 // Datagram socket. 357 // 358 class Pj_Sock_Dgram : public Pj_Socket 178 359 { 179 360 public: 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; 193 422 } 194 423 }; 195 424 425 196 426 #endif /* __PJPP_SOCK_H__ */ -
pjproject/main/pjlib/include/pj++/string.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_STRING_H__ … … 7 6 #include <pj/string.h> 8 7 #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 // 13 class Pj_String : public pj_str_t 11 14 { 12 15 public: 13 PJ_String() 16 // 17 // Default constructor. 18 // 19 Pj_String() 14 20 { 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) 20 30 { 21 31 set(str); 22 32 } 23 33 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) 25 38 { 26 39 set(pool, src); 27 40 } 28 41 29 explicit PJ_String(pj_str_t *s) 42 // 43 // Construct from pj_str_t*. 44 // 45 explicit Pj_String(pj_str_t *s) 30 46 { 31 47 set(s); 32 48 } 33 49 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) 35 54 { 36 55 set(pool, s); 37 56 } 38 57 39 explicit PJ_String(PJ_String &rhs) 58 // 59 // Construct from another Pj_String 60 // 61 explicit Pj_String(Pj_String &rhs) 40 62 { 41 63 set(rhs); 42 64 } 43 65 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) 45 70 { 46 71 set(pool, rhs); 47 72 } 48 73 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) 50 78 { 51 79 set(str, len); 52 80 } 53 81 54 PJ_String(char *begin, char *end) 82 // 83 // Construct from pair of pointer. 84 // 85 Pj_String(char *begin, char *end) 55 86 { 56 87 pj_strset3(this, begin, end); 57 88 } 58 89 90 // 91 // Get the length of the string. 92 // 59 93 pj_size_t length() const 60 94 { … … 62 96 } 63 97 98 // 99 // Get the length of the string. 100 // 64 101 pj_size_t size() const 65 102 { … … 67 104 } 68 105 106 // 107 // Get the string buffer. 108 // 69 109 const char *buf() const 70 110 { … … 72 112 } 73 113 114 // 115 // Initialize buffer from char*. 116 // 74 117 void set(char *str) 75 118 { … … 77 120 } 78 121 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) 80 126 { 81 127 pj_strdup2(pool->pool_(), this, s); 82 128 } 83 129 130 // 131 // Initialize from pj_str_t*. 132 // 84 133 void set(pj_str_t *s) 85 134 { … … 87 136 } 88 137 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) 90 142 { 91 143 pj_strdup(pool->pool_(), this, s); 92 144 } 93 145 146 // 147 // Initialize from char* and length. 148 // 94 149 void set(char *str, pj_size_t len) 95 150 { … … 97 152 } 98 153 154 // 155 // Initialize from pair of pointers. 156 // 99 157 void set(char *begin, char *end) 100 158 { … … 102 160 } 103 161 104 void set(PJ_String &rhs) 162 // 163 // Initialize from other Pj_String. 164 // 165 void set(Pj_String &rhs) 105 166 { 106 167 pj_strassign(this, &rhs); 107 168 } 108 169 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) 110 174 { 111 175 pj_strdup(pool->pool_(), this, s); 112 176 } 113 177 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) 115 182 { 116 183 pj_strdup(pool->pool_(), this, &s); 117 184 } 118 185 186 // 187 // Copy the contents of other string. 188 // 119 189 void strcpy(const pj_str_t *s) 120 190 { … … 122 192 } 123 193 124 void strcpy(const PJ_String &rhs) 194 // 195 // Copy the contents of other string. 196 // 197 void strcpy(const Pj_String &rhs) 125 198 { 126 199 pj_strcpy(this, &rhs); 127 200 } 128 201 202 // 203 // Copy the contents of other string. 204 // 129 205 void strcpy(const char *s) 130 206 { … … 132 208 } 133 209 210 // 211 // Compare string. 212 // 134 213 int strcmp(const char *s) const 135 214 { … … 137 216 } 138 217 218 // 219 // Compare string. 220 // 139 221 int strcmp(const pj_str_t *s) const 140 222 { … … 142 224 } 143 225 144 int strcmp(const PJ_String &rhs) const 226 // 227 // Compare string. 228 // 229 int strcmp(const Pj_String &rhs) const 145 230 { 146 231 return pj_strcmp(this, &rhs); 147 232 } 148 233 234 // 235 // Compare string. 236 // 149 237 int strncmp(const char *s, pj_size_t len) const 150 238 { … … 152 240 } 153 241 242 // 243 // Compare string. 244 // 154 245 int strncmp(const pj_str_t *s, pj_size_t len) const 155 246 { … … 157 248 } 158 249 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 160 254 { 161 255 return pj_strncmp(this, &rhs, len); 162 256 } 163 257 258 // 259 // Compare string. 260 // 164 261 int stricmp(const char *s) const 165 262 { … … 167 264 } 168 265 266 // 267 // Compare string. 268 // 169 269 int stricmp(const pj_str_t *s) const 170 270 { … … 172 272 } 173 273 174 int stricmp(const PJ_String &rhs) const 274 // 275 // Compare string. 276 // 277 int stricmp(const Pj_String &rhs) const 175 278 { 176 279 return stricmp(&rhs); 177 280 } 178 281 282 // 283 // Compare string. 284 // 179 285 int strnicmp(const char *s, pj_size_t len) const 180 286 { … … 182 288 } 183 289 290 // 291 // Compare string. 292 // 184 293 int strnicmp(const pj_str_t *s, pj_size_t len) const 185 294 { … … 187 296 } 188 297 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 190 302 { 191 303 return strnicmp(&rhs, len); 192 304 } 193 305 306 // 307 // Compare contents for equality. 308 // 194 309 bool operator==(const char *s) const 195 310 { … … 197 312 } 198 313 314 // 315 // Compare contents for equality. 316 // 199 317 bool operator==(const pj_str_t *s) const 200 318 { … … 202 320 } 203 321 204 bool operator==(const PJ_String &rhs) const 322 // 323 // Compare contents for equality. 324 // 325 bool operator==(const Pj_String &rhs) const 205 326 { 206 327 return pj_strcmp(this, &rhs) == 0; 207 328 } 208 329 330 // 331 // Find a character in the string. 332 // 209 333 char *strchr(int chr) 210 334 { … … 212 336 } 213 337 338 // 339 // Find a character in the string. 340 // 214 341 char *find(int chr) 215 342 { … … 217 344 } 218 345 219 void strcat(const PJ_String &rhs) 346 // 347 // Concatenate string. 348 // 349 void strcat(const Pj_String &rhs) 220 350 { 221 351 pj_strcat(this, &rhs); 222 352 } 223 353 354 // 355 // Left trim. 356 // 224 357 void ltrim() 225 358 { … … 227 360 } 228 361 362 // 363 // Right trim. 364 // 229 365 void rtrim() 230 366 { … … 232 368 } 233 369 370 // 371 // Left and right trim. 372 // 234 373 void trim() 235 374 { … … 237 376 } 238 377 239 unsigned long toul() const 378 // 379 // Convert to unsigned long. 380 // 381 unsigned long to_ulong() const 240 382 { 241 383 return pj_strtoul(this); 242 384 } 243 385 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 244 403 private: 245 //P J_String(const PJ_String &rhs) {}246 void operator=(const P J_String &rhs) { pj_assert(false); }404 //Pj_String(const Pj_String &rhs) {} 405 void operator=(const Pj_String &rhs) { pj_assert(false); } 247 406 }; 248 407 -
pjproject/main/pjlib/include/pj++/timer.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_TIMER_H__ … … 7 6 #include <pj/timer.h> 8 7 #include <pj++/types.hpp> 8 #include <pj/assert.h> 9 #include <pj++/lock.hpp> 9 10 10 class P J_Timer_Heap;11 class Pj_Timer_Heap; 11 12 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 // 20 class Pj_Timer_Entry : public Pj_Object 13 21 { 14 friend class P J_Timer_Heap;22 friend class Pj_Timer_Heap; 15 23 16 24 public: 17 static void timer_heap_callback(pj_timer_heap_t *, pj_timer_entry *);18 19 PJ_Timer_Entry() { cb = &timer_heap_callback; }20 P J_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; 24 32 } 25 33 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() 29 38 { 30 id = arg_id;31 user_data = arg_user_data;32 39 } 33 40 34 int get_id() const 41 // 42 // Override this to get the timeout notification. 43 // 44 virtual void on_timeout(int id) = 0; 45 46 private: 47 pj_timer_entry entry_; 48 49 static void timer_heap_callback(pj_timer_heap_t *th, pj_timer_entry *e) 35 50 { 36 return id; 51 Pj_Timer_Entry *entry = (Pj_Timer_Entry*) e->user_data; 52 entry->on_timeout(e->id); 37 53 } 38 54 39 void set_id(int arg_id) 55 }; 56 57 ////////////////////////////////////////////////////////////////////////////// 58 // Timer heap. 59 // 60 class Pj_Timer_Heap : public Pj_Object 61 { 62 public: 63 // 64 // Default constructor. 65 // 66 Pj_Timer_Heap() 67 : ht_(NULL) 40 68 { 41 id = arg_id;42 69 } 43 70 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) 45 76 { 46 user_data = arg_user_data;77 create(pool, initial_count); 47 78 } 48 79 49 void *get_user_data() const 80 // 81 // Destructor. 82 // 83 ~Pj_Timer_Heap() 50 84 { 51 return user_data;85 destroy(); 52 86 } 53 87 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) 55 92 { 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_); 71 95 } 72 96 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 // 73 111 pj_timer_heap_t *get_timer_heap() 74 112 { … … 76 114 } 77 115 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 ) 79 120 { 80 return pj_timer_heap_schedule(ht_, ent, &delay) == 0;121 pj_timer_heap_set_lock( ht_, lock->pj_lock_t_(), auto_delete); 81 122 } 82 123 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) 84 128 { 85 return pj_timer_heap_cancel(ht_, ent) == 1;129 return pj_timer_heap_set_max_timed_out_per_poll(ht_, count); 86 130 } 87 131 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 // 88 153 pj_size_t count() 89 154 { … … 91 156 } 92 157 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) 94 163 { 95 pj_timer_heap_earliest_time(ht_, t);164 return pj_timer_heap_earliest_time(ht_, t) == PJ_SUCCESS; 96 165 } 97 166 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) 99 172 { 100 173 return pj_timer_heap_poll(ht_, next_delay); -
pjproject/main/pjlib/include/pj++/tree.hpp
r29 r36 7 7 #include <pj/rbtree.h> 8 8 9 // 10 // Tree. 11 // 9 12 class PJ_Tree 10 13 { -
pjproject/main/pjlib/include/pj++/types.hpp
r29 r36 7 7 #include <pj/types.h> 8 8 9 class PJ_Pool; 10 class PJ_Socket; 9 class Pj_Pool; 10 class Pj_Socket ; 11 class Pj_Lock; 11 12 12 13 13 class PJ_Time_Val : public pj_time_val 14 // 15 // PJLIB initializer. 16 // 17 class Pjlib 14 18 { 15 19 public: 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 }; 19 25 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 // 25 29 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 // 33 class Pj_Time_Val : public pj_time_val 34 { 35 public: 36 Pj_Time_Val() 37 { 38 } 31 39 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 { 33 111 sec = rhs.sec; 34 112 msec = rhs.msec; … … 36 114 } 37 115 38 PJ_Time_Val & operator += (const PJ_Time_Val &rhs) { 116 Pj_Time_Val & operator += (const Pj_Time_Val &rhs) 117 { 39 118 PJ_TIME_VAL_ADD((*this), rhs); 40 119 return *this; 41 120 } 42 121 43 PJ_Time_Val & operator -= (const PJ_Time_Val &rhs) { 122 Pj_Time_Val & operator -= (const Pj_Time_Val &rhs) 123 { 44 124 PJ_TIME_VAL_SUB((*this), rhs); 45 125 return *this; … … 47 127 48 128 /* Must include os.hpp to use these, otherwise unresolved in linking */ 49 pj_status_t gettimeofday();50 pj_parsed_timedecode();51 pj_status_tencode(const pj_parsed_time *pt);52 pj_status_tto_gmt();53 pj_status_tto_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(); 54 134 55 135 56 136 private: 57 void normalize() { pj_time_val_normalize(this); } 137 void normalize() 138 { 139 pj_time_val_normalize(this); 140 } 58 141 59 142 }; -
pjproject/main/pjlib/include/pj/errno.h
r4 r36 211 211 */ 212 212 #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) 213 218 214 219 /** @} */ /* pj_errnum */ -
pjproject/main/pjlib/include/pj/ioqueue.h
r19 r36 298 298 /** 299 299 * 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. 304 307 * 305 308 * @param key The key that was previously obtained from registration. 306 309 * 307 310 * @return PJ_SUCCESS on success or the error code. 311 * 312 * @see pj_ioqueue_is_pending 308 313 */ 309 314 PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key ); … … 334 339 void *user_data, 335 340 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 */ 354 PJ_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 */ 372 PJ_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 336 376 337 377 -
pjproject/main/pjlib/include/pj/os.h
r5 r36 326 326 327 327 /** 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 */ 334 PJ_DECL(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var); 335 336 /** 328 337 * Decrement the value of an atomic type. 329 338 * … … 331 340 */ 332 341 PJ_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 */ 350 PJ_DECL(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var); 333 351 334 352 /** … … 340 358 PJ_DECL(void) pj_atomic_add( pj_atomic_t *atomic_var, 341 359 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 */ 369 PJ_DECL(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var, 370 pj_atomic_value_t value); 342 371 343 372 /** -
pjproject/main/pjlib/include/pj/timer.h
r4 r36 111 111 112 112 /** 113 * Default flag for timer heap, indicates that synchronization will be114 * used.115 */116 #define PJ_TIMER_HEAP_SYNCHRONIZE (0)117 118 /**119 * Flag to indicate that thread synchronization is NOT needed for the120 * timer heap.121 */122 #define PJ_TIMER_HEAP_NO_SYNCHRONIZE (1)123 124 /**125 113 * Calculate memory size required to create a timer heap. 126 114 * … … 141 129 * initially. If the application registers more entries 142 130 * during runtime, then the timer heap will resize. 143 * @param flag Creation flag, currently only PJ_TIMER_HEAP_NO_SYNCHRONIZE144 * is recognized..145 131 * @param ht Pointer to receive the created timer heap. 146 132 * … … 149 135 PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool, 150 136 pj_size_t count, 151 unsigned flag,152 137 pj_timer_heap_t **ht); 138 139 /** 140 * Destroy the timer heap. 141 * 142 * @param ht The timer heap. 143 */ 144 PJ_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 */ 156 PJ_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 */ 168 PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht, 169 unsigned count ); 153 170 154 171 /** … … 216 233 */ 217 234 PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht, 218 pj_time_val *timeval);235 pj_time_val *timeval); 219 236 220 237 /** … … 222 239 * each of the expired timers. 223 240 * 224 * @param ht The timer heap.241 * @param ht The timer heap. 225 242 * @param next_delay If this parameter is not NULL, it will be filled up with 226 243 * the time delay until the next timer elapsed, or -1 in 227 244 * 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 */ 248 PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, 249 pj_time_val *next_delay); 231 250 232 251 /** -
pjproject/main/pjlib/src/pj/errno.c
r6 r36 30 30 { PJ_EBUSY, "Object is busy"}, 31 31 { PJ_ENOTSUP, "Option/operation is not supported"}, 32 { PJ_EINVALIDOP, "Invalid operation"} 32 { PJ_EINVALIDOP, "Invalid operation"}, 33 { PJ_ECANCELLED, "Operation cancelled"} 33 34 }; 34 35 -
pjproject/main/pjlib/src/pj/file_io_ansi.c
r18 r36 68 68 written = fwrite(data, 1, *size, (FILE*)fd); 69 69 if (ferror((FILE*)fd)) { 70 *size = -1; 70 71 return PJ_RETURN_OS_ERROR(errno); 71 72 } … … 84 85 bytes = fread(data, 1, *size, (FILE*)fd); 85 86 if (ferror((FILE*)fd)) { 87 *size = -1; 86 88 return PJ_RETURN_OS_ERROR(errno); 87 89 } -
pjproject/main/pjlib/src/pj/ioqueue_common_abs.c
r35 r36 229 229 if (h->fd_type == PJ_SOCK_DGRAM) { 230 230 pj_list_erase(write_op); 231 write_op->op = 0; 232 231 233 if (pj_list_empty(&h->write_list)) 232 234 ioqueue_remove_from_set(ioqueue, h->fd, WRITEABLE_EVENT); … … 269 271 /* Write completion of the whole stream. */ 270 272 pj_list_erase(write_op); 273 write_op->op = 0; 271 274 272 275 /* Clear operation if there's no more data to send. */ … … 315 318 accept_op = h->accept_list.next; 316 319 pj_list_erase(accept_op); 320 accept_op->op = 0; 317 321 318 322 /* Clear bit in fdset if there is no more pending accept */ … … 348 352 read_op = h->read_list.next; 349 353 pj_list_erase(read_op); 354 read_op->op = 0; 350 355 351 356 /* Clear fdset if there is no pending read. */ … … 477 482 PJ_CHECK_STACK(); 478 483 484 read_op = (struct read_operation*)op_key; 485 read_op->op = 0; 486 479 487 /* Try to see if there's data immediately available. 480 488 */ … … 497 505 * Must schedule asynchronous operation to the ioqueue. 498 506 */ 499 read_op = (struct read_operation*)op_key;500 501 507 read_op->op = PJ_IOQUEUE_OP_RECV; 502 508 read_op->buf = buffer; … … 531 537 PJ_ASSERT_RETURN(key && op_key && buffer && length, PJ_EINVAL); 532 538 PJ_CHECK_STACK(); 539 540 read_op = (struct read_operation*)op_key; 541 read_op->op = 0; 533 542 534 543 /* Try to see if there's data immediately available. … … 553 562 * Must schedule asynchronous operation to the ioqueue. 554 563 */ 555 read_op = (struct read_operation*)op_key;556 557 564 read_op->op = PJ_IOQUEUE_OP_RECV_FROM; 558 565 read_op->buf = buffer; … … 587 594 PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL); 588 595 PJ_CHECK_STACK(); 596 597 write_op = (struct write_operation*)op_key; 598 write_op->op = 0; 589 599 590 600 /* Fast track: … … 625 635 * Schedule asynchronous send. 626 636 */ 627 write_op = (struct write_operation*)op_key;628 637 write_op->op = PJ_IOQUEUE_OP_SEND; 629 638 write_op->buf = (void*)data; … … 660 669 PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL); 661 670 PJ_CHECK_STACK(); 671 672 write_op = (struct write_operation*)op_key; 673 write_op->op = 0; 662 674 663 675 /* Fast track: … … 703 715 * Schedule asynchronous send. 704 716 */ 705 write_op = (struct write_operation*)op_key;706 717 write_op->op = PJ_IOQUEUE_OP_SEND_TO; 707 718 write_op->buf = (void*)data; … … 736 747 /* check parameters. All must be specified! */ 737 748 PJ_ASSERT_RETURN(key && op_key && new_sock, PJ_EINVAL); 749 750 accept_op = (struct accept_operation*)op_key; 751 accept_op->op = 0; 738 752 739 753 /* Fast track: … … 768 782 * connection available. 769 783 */ 770 accept_op = (struct accept_operation*)op_key;771 772 784 accept_op->op = PJ_IOQUEUE_OP_ACCEPT; 773 785 accept_op->accept_fd = new_sock; … … 822 834 #endif /* PJ_HAS_TCP */ 823 835 836 /* 837 * pj_ioqueue_is_pending() 838 */ 839 PJ_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 */ 854 PJ_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 892 892 #endif /* #if PJ_HAS_TCP */ 893 893 894 895 896 PJ_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 913 PJ_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 560 560 561 561 /* 562 * pj_atomic_inc_and_get() 563 */ 564 PJ_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 /* 562 581 * pj_atomic_inc() 563 582 */ 564 583 PJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var) 565 584 { 585 pj_atomic_inc_and_get(atomic_var); 586 } 587 588 /* 589 * pj_atomic_dec_and_get() 590 */ 591 PJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var) 592 { 593 pj_atomic_value_t new_value; 594 566 595 PJ_CHECK_STACK(); 567 596 … … 569 598 pj_mutex_lock( atomic_var->mutex ); 570 599 #endif 571 ++atomic_var->value;600 new_value = --atomic_var->value; 572 601 #if PJ_HAS_THREADS 573 602 pj_mutex_unlock( atomic_var->mutex); 574 603 #endif 604 605 return new_value; 575 606 } 576 607 … … 580 611 PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var) 581 612 { 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 */ 619 PJ_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; 591 636 } 592 637 … … 594 639 * pj_atomic_add() 595 640 */ 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 641 PJ_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 } 609 646 610 647 /////////////////////////////////////////////////////////////////////////////// -
pjproject/main/pjlib/src/pj/os_core_win32.c
r6 r36 514 514 515 515 /* 516 * pj_atomic_inc ()517 */ 518 PJ_DEF( void) pj_atomic_inc(pj_atomic_t *atomic_var)516 * pj_atomic_inc_and_get() 517 */ 518 PJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var) 519 519 { 520 520 PJ_CHECK_STACK(); 521 521 522 522 #if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 523 InterlockedIncrement(&atomic_var->value);523 return InterlockedIncrement(&atomic_var->value); 524 524 #else 525 525 # error Fix Me … … 528 528 529 529 /* 530 * pj_atomic_dec() 531 */ 532 PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var) 530 * pj_atomic_inc() 531 */ 532 PJ_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 */ 540 PJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var) 533 541 { 534 542 PJ_CHECK_STACK(); 535 543 536 544 #if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 537 InterlockedDecrement(&atomic_var->value);545 return InterlockedDecrement(&atomic_var->value); 538 546 #else 539 547 # error Fix me … … 542 550 543 551 /* 552 * pj_atomic_dec() 553 */ 554 PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var) 555 { 556 pj_atomic_dec_and_get(atomic_var); 557 } 558 559 /* 544 560 * pj_atomic_add() 545 561 */ … … 547 563 pj_atomic_value_t value ) 548 564 { 565 #if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400 549 566 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 */ 575 PJ_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 553 586 /////////////////////////////////////////////////////////////////////////////// 554 587 /* -
pjproject/main/pjlib/src/pj/timer.c
r6 r36 15 15 #include <pj/assert.h> 16 16 #include <pj/errno.h> 17 #include <pj/lock.h> 17 18 18 19 #define HEAP_PARENT(X) (X == 0 ? 0 : (((X) - 1) / 2)) 19 20 #define HEAP_LEFT(X) (((X)+(X))+1) 21 22 23 #define DEFAULT_MAX_TIMED_OUT_PER_POLL (64) 20 24 21 25 … … 34 38 pj_size_t cur_size; 35 39 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; 38 48 39 49 /** … … 72 82 PJ_INLINE(void) lock_timer_heap( pj_timer_heap_t *ht ) 73 83 { 74 if (ht-> mutex) {75 pj_ mutex_lock(ht->mutex);84 if (ht->lock) { 85 pj_lock_acquire(ht->lock); 76 86 } 77 87 } … … 79 89 PJ_INLINE(void) unlock_timer_heap( pj_timer_heap_t *ht ) 80 90 { 81 if (ht-> mutex) {82 pj_ mutex_unlock(ht->mutex);91 if (ht->lock) { 92 pj_lock_release(ht->lock); 83 93 } 84 94 } … … 320 330 /* size of each entry: */ 321 331 (count+2) * (sizeof(pj_timer_entry*)+sizeof(pj_timer_id_t)) + 322 /* mutex, pool etc: */332 /* lock, pool etc: */ 323 333 132; 324 334 } … … 329 339 PJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool, 330 340 pj_size_t size, 331 unsigned flag,332 341 pj_timer_heap_t **p_heap) 333 342 { … … 350 359 ht->max_size = size; 351 360 ht->cur_size = 0; 361 ht->max_entries_per_poll = DEFAULT_MAX_TIMED_OUT_PER_POLL; 352 362 ht->timer_ids_freelist = 1; 353 363 ht->pool = pool; 354 364 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; 368 368 369 369 // Create the heap array. … … 387 387 } 388 388 389 PJ_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 397 PJ_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 409 PJ_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 389 417 PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry, 390 418 int id, … … 434 462 } 435 463 436 PJ_DEF(int) pj_timer_heap_poll( pj_timer_heap_t *ht, pj_time_val *next_delay ) 464 PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, 465 pj_time_val *next_delay ) 437 466 { 438 467 pj_time_val now; 439 intcount;440 441 PJ_ASSERT_RETURN(ht, -1);468 unsigned count; 469 470 PJ_ASSERT_RETURN(ht, 0); 442 471 443 472 if (!ht->cur_size && next_delay) { … … 451 480 lock_timer_heap(ht); 452 481 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 ) 454 484 { 455 485 pj_timer_entry *node = remove_node(ht, 0); 456 486 ++count; 457 487 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); 461 489 (*node->cb)(ht, node); 462 //lock_timer_heap(ht);490 lock_timer_heap(ht); 463 491 } 464 492 if (ht->cur_size && next_delay) { … … 475 503 PJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht ) 476 504 { 505 PJ_ASSERT_RETURN(ht, 0); 506 477 507 return ht->cur_size; 478 508 }
Note: See TracChangeset
for help on using the changeset viewer.