summaryrefslogtreecommitdiff
path: root/pjlib/include/pj++
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2005-11-09 15:37:19 +0000
committerBenny Prijono <bennylp@teluu.com>2005-11-09 15:37:19 +0000
commit6e1024262b48b57b771331b8c19e988e43627bd7 (patch)
treea43fdaeb6d7b22cc7afab1633622bf55d39dfd67 /pjlib/include/pj++
parentfb9e3b3a6649cc5cbe0c6747cb1918f3be71ba06 (diff)
Rework pjlib++
git-svn-id: http://svn.pjsip.org/repos/pjproject/main@36 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/include/pj++')
-rw-r--r--pjlib/include/pj++/file.hpp171
-rw-r--r--pjlib/include/pj++/hash.hpp110
-rw-r--r--pjlib/include/pj++/ioqueue.hpp174
-rw-r--r--pjlib/include/pj++/list.hpp226
-rw-r--r--pjlib/include/pj++/lock.hpp131
-rw-r--r--pjlib/include/pj++/os.hpp643
-rw-r--r--pjlib/include/pj++/pool.hpp206
-rw-r--r--pjlib/include/pj++/proactor.hpp483
-rw-r--r--pjlib/include/pj++/scanner.hpp30
-rw-r--r--pjlib/include/pj++/sock.hpp364
-rw-r--r--pjlib/include/pj++/string.hpp215
-rw-r--r--pjlib/include/pj++/timer.hpp161
-rw-r--r--pjlib/include/pj++/tree.hpp3
-rw-r--r--pjlib/include/pj++/types.hpp139
14 files changed, 2459 insertions, 597 deletions
diff --git a/pjlib/include/pj++/file.hpp b/pjlib/include/pj++/file.hpp
new file mode 100644
index 00000000..dfd78d51
--- /dev/null
+++ b/pjlib/include/pj++/file.hpp
@@ -0,0 +1,171 @@
+/* $Id$ */
+
+#ifndef __PJPP_FILE_HPP__
+#define __PJPP_FILE_HPP__
+
+#include <pj/file_io.h>
+#include <pj/file_access.h>
+#include <pj++/types.hpp>
+#include <pj++/pool.hpp>
+
+//
+// File API.
+//
+class Pj_File_API
+{
+public:
+ //
+ // Check file existance.
+ //
+ static bool file_exists(const char *filename)
+ {
+ return pj_file_exists(filename) != 0;
+ }
+
+ //
+ // Get file size.
+ //
+ static pj_off_t file_size(const char *filename)
+ {
+ return pj_file_size(filename);
+ }
+
+ //
+ // Delete file.
+ //
+ static pj_status_t file_delete(const char *filename)
+ {
+ return pj_file_delete(filename);
+ }
+
+ //
+ // Move/rename file.
+ //
+ static pj_status_t file_move(const char *oldname, const char *newname)
+ {
+ return pj_file_move(oldname, newname);
+ }
+
+ //
+ // Get stat.
+ //
+ static pj_status_t file_stat(const char *filename, pj_file_stat *buf)
+ {
+ return pj_file_getstat(filename, buf);
+ }
+};
+
+
+//
+// File.
+//
+class Pj_File : public Pj_Object
+{
+public:
+ //
+ // Offset type to be used in setpos.
+ //
+ enum Offset_Type
+ {
+ SEEK_SET = PJ_SEEK_SET,
+ SEEK_CUR = PJ_SEEK_CUR,
+ SEEK_END = PJ_SEEK_END,
+ };
+
+ //
+ // Default constructor.
+ //
+ Pj_File()
+ : hnd_(0)
+ {
+ }
+
+ //
+ // Construct and open a file.
+ //
+ Pj_File(Pj_Pool *pool, const char *filename,
+ unsigned access = PJ_O_RDONLY)
+ : hnd_(NULL)
+ {
+ open(pool, filename, access);
+ }
+
+ //
+ // Destructor closes the file.
+ //
+ ~Pj_File()
+ {
+ close();
+ }
+
+ //
+ // Open a file.
+ //
+ pj_status_t open(Pj_Pool *pool, const char *filename,
+ unsigned access = PJ_O_RDONLY )
+ {
+ close();
+ return pj_file_open(pool->pool_(), filename, access, &hnd_);
+ }
+
+ //
+ // Close a file.
+ //
+ void close()
+ {
+ if (hnd_ != 0) {
+ pj_file_close(hnd_);
+ hnd_ = 0;
+ }
+ }
+
+ //
+ // Write data.
+ //
+ pj_ssize_t write(const void *buff, pj_size_t size)
+ {
+ pj_ssize_t bytes = size;
+ if (pj_file_write(hnd_, buff, &bytes) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // Read data.
+ //
+ pj_ssize_t read(void *buf, pj_size_t size)
+ {
+ pj_ssize_t bytes = size;
+ if (pj_file_read(hnd_, buf, &bytes) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // Set file position.
+ //
+ pj_status_t setpos(pj_off_t offset, Offset_Type whence)
+ {
+ return pj_file_setpos(hnd_, offset,
+ (enum pj_file_seek_type)whence);
+ }
+
+ //
+ // Get file position.
+ //
+ pj_off_t getpos()
+ {
+ pj_off_t pos;
+ if (pj_file_getpos(hnd_, &pos) != PJ_SUCCESS)
+ return -1;
+ return pos;
+ }
+
+private:
+ pj_oshandle_t hnd_;
+};
+
+
+
+#endif /* __PJPP_FILE_HPP__ */
+
diff --git a/pjlib/include/pj++/hash.hpp b/pjlib/include/pj++/hash.hpp
index 26f48010..6d4a5e68 100644
--- a/pjlib/include/pj++/hash.hpp
+++ b/pjlib/include/pj++/hash.hpp
@@ -1,73 +1,139 @@
/* $Id$
- *
*/
#ifndef __PJPP_HASH_H__
#define __PJPP_HASH_H__
#include <pj++/types.hpp>
+#include <pj++/pool.hpp>
#include <pj/hash.h>
-class PJ_Hash_Table
+//
+// Hash table.
+//
+class Pj_Hash_Table : public Pj_Object
{
public:
+ //
+ // Hash table iterator.
+ //
class iterator
{
public:
- iterator() {}
- explicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i) : ht_(h), it_(i) {}
- iterator(const iterator &rhs) : ht_(rhs.ht_), it_(rhs.it_) {}
- void operator++() { it_ = pj_hash_next(ht_, it_); }
- bool operator==(const iterator &rhs) { return ht_ == rhs.ht_ && it_ == rhs.it_; }
- iterator & operator=(const iterator &rhs) { ht_=rhs.ht_; it_=rhs.it_; return *this; }
+ iterator()
+ {
+ }
+ explicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i)
+ : ht_(h), it_(i)
+ {
+ }
+ iterator(const iterator &rhs)
+ : ht_(rhs.ht_), it_(rhs.it_)
+ {
+ }
+ void operator++()
+ {
+ it_ = pj_hash_next(ht_, it_);
+ }
+ bool operator==(const iterator &rhs)
+ {
+ return ht_ == rhs.ht_ && it_ == rhs.it_;
+ }
+ iterator & operator=(const iterator &rhs)
+ {
+ ht_=rhs.ht_; it_=rhs.it_;
+ return *this;
+ }
private:
pj_hash_table_t *ht_;
pj_hash_iterator_t it_val_;
pj_hash_iterator_t *it_;
- friend class PJ_Hash_Table;
+ friend class Pj_Hash_Table;
};
- static PJ_Hash_Table *create(PJ_Pool *pool, unsigned size)
+ //
+ // Construct hash table.
+ //
+ Pj_Hash_Table(Pj_Pool *pool, unsigned size)
{
- return (PJ_Hash_Table*) pj_hash_create(pool->pool_(), size);
+ table_ = pj_hash_create(pool->pool_(), size);
}
- static pj_uint32_t calc(pj_uint32_t initial_hval, const void *key, unsigned keylen)
+ //
+ // Destroy hash table.
+ //
+ ~Pj_Hash_Table()
+ {
+ }
+
+ //
+ // Calculate hash value.
+ //
+ static pj_uint32_t calc( pj_uint32_t initial_hval,
+ const void *key,
+ unsigned keylen = PJ_HASH_KEY_STRING)
{
return pj_hash_calc(initial_hval, key, keylen);
}
- pj_hash_table_t *hash_table_()
+ //
+ // Return pjlib compatible hash table object.
+ //
+ pj_hash_table_t *pj_hash_table_t_()
{
- return (pj_hash_table_t*)this;
+ return table_;
}
- void *get(const void *key, unsigned keylen)
+ //
+ // Get the value associated with the specified key.
+ //
+ void *get(const void *key, unsigned keylen = PJ_HASH_KEY_STRING)
{
- return pj_hash_get(this->hash_table_(), key, keylen);
+ return pj_hash_get(table_, key, keylen);
}
- void set(PJ_Pool *pool, const void *key, unsigned keylen, void *value)
+ //
+ // Associate a value with a key.
+ // Set the value to NULL to delete the key from the hash table.
+ //
+ void set(Pj_Pool *pool,
+ const void *key,
+ void *value,
+ unsigned keylen = PJ_HASH_KEY_STRING)
{
- pj_hash_set(pool->pool_(), this->hash_table_(), key, keylen, value);
+ pj_hash_set(pool->pool_(), table_, key, keylen, value);
}
+ //
+ // Get number of items in the hash table.
+ //
unsigned count()
{
- return pj_hash_count(this->hash_table_());
+ return pj_hash_count(table_);
}
+ //
+ // Iterate hash table.
+ //
iterator begin()
{
- iterator it(this->hash_table_(), NULL);
- it.it_ = pj_hash_first(this->hash_table_(), &it.it_val_);
+ iterator it(table_, NULL);
+ it.it_ = pj_hash_first(table_, &it.it_val_);
return it;
}
+ //
+ // End of items.
+ //
iterator end()
{
- return iterator(this->hash_table_(), NULL);
+ return iterator(table_, NULL);
}
+
+private:
+ pj_hash_table_t *table_;
};
+
#endif /* __PJPP_HASH_H__ */
+
diff --git a/pjlib/include/pj++/ioqueue.hpp b/pjlib/include/pj++/ioqueue.hpp
deleted file mode 100644
index 5724ecd6..00000000
--- a/pjlib/include/pj++/ioqueue.hpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* $Id$
- *
- */
-#ifndef __PJPP_IOQUEUE_H__
-#define __PJPP_IOQUEUE_H__
-
-#include <pj++/sock.hpp>
-#include <pj++/pool.hpp>
-#include <pj++/types.hpp>
-#include <pj/ioqueue.h>
-
-class PJ_IOQueue;
-
-class PJ_IOQueue_Event_Handler
-{
-public:
- virtual ~PJ_IOQueue_Event_Handler()
- {
- }
-
- pj_ioqueue_key_t* get_key() const
- {
- return key_;
- }
-
-protected:
- //
- // Override this to get notification from I/O Queue
- //
- virtual void on_read_complete(pj_ssize_t bytes_read)
- {
- }
-
- virtual void on_write_complete(pj_ssize_t bytes_sent)
- {
- }
-
- virtual void on_accept_complete(int status)
- {
- }
-
- virtual void on_connect_complete(int status)
- {
- }
-
-protected:
- PJ_IOQueue_Event_Handler()
- : ioqueue_(NULL), key_(NULL)
- {
- }
-
-private:
- PJ_IOQueue *ioqueue_;
- pj_ioqueue_key_t *key_;
-
- static void read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read)
- {
- PJ_IOQueue_Event_Handler *handler =
- (PJ_IOQueue_Event_Handler*)pj_ioqueue_get_user_data(key);
- handler->on_read_complete(bytes_read);
- }
-
- static void write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent);
- static void accept_complete_cb(pj_ioqueue_key_t *key, int status);
- static void connect_complete_cb(pj_ioqueue_key_t *key, int status);
-
- friend class PJ_IOQueue;
-};
-
-
-class PJ_IOQueue
-{
- typedef pj_ioqueue_t *B_;
-
-public:
- typedef pj_ioqueue_key_t Key;
-
- enum Operation
- {
- OP_NONE = PJ_IOQUEUE_OP_NONE,
- OP_READ = PJ_IOQUEUE_OP_READ,
- OP_RECV_FROM = PJ_IOQUEUE_OP_RECV_FROM,
- OP_WRITE = PJ_IOQUEUE_OP_WRITE,
- OP_SEND_TO = PJ_IOQUEUE_OP_SEND_TO,
-#if PJ_HAS_TCP
- OP_ACCEPT = PJ_IOQUEUE_OP_ACCEPT,
- OP_CONNECT = PJ_IOQUEUE_OP_CONNECT,
-#endif
- };
-
- enum Status
- {
- IS_PENDING = PJ_IOQUEUE_PENDING
- };
-
- static PJ_IOQueue *create(PJ_Pool *pool, pj_size_t max_fd)
- {
- return (PJ_IOQueue*) pj_ioqueue_create(pool->pool_(), max_fd);
- }
-
- operator B_()
- {
- return (pj_ioqueue_t*)(PJ_IOQueue*)this;
- }
-
- pj_ioqueue_t *ioq_()
- {
- return (B_)this;
- }
-
- void destroy()
- {
- pj_ioqueue_destroy(this->ioq_());
- }
-
- Key *register_handle(PJ_Pool *pool, pj_oshandle_t hnd, void *user_data)
- {
- return pj_ioqueue_register(pool->pool_(), this->ioq_(), hnd, user_data);
- }
-
- Key *register_socket(PJ_Pool *pool, pj_sock_t hnd, void *user_data)
- {
- return pj_ioqueue_register(pool->pool_(), this->ioq_(), (pj_oshandle_t)hnd, user_data);
- }
-
- pj_status_t unregister(Key *key)
- {
- return pj_ioqueue_unregister(this->ioq_(), key);
- }
-
- void *get_user_data(Key *key)
- {
- return pj_ioqueue_get_user_data(key);
- }
-
- int poll(Key **key, pj_ssize_t *bytes_status, Operation *op, const PJ_Time_Val *timeout)
- {
- return pj_ioqueue_poll(this->ioq_(), key, bytes_status, (pj_ioqueue_operation_e*)op, timeout);
- }
-
-#if PJ_HAS_TCP
- pj_status_t connect(Key *key, const pj_sockaddr_t *addr, int addrlen)
- {
- return pj_ioqueue_connect(this->ioq_(), key, addr, addrlen);
- }
-
- pj_status_t accept(Key *key, PJ_Socket *sock, pj_sockaddr_t *local, pj_sockaddr_t *remote, int *addrlen)
- {
- return pj_ioqueue_accept(this->ioq_(), key, &sock->get_handle(), local, remote, addrlen);
- }
-#endif
-
- int read(Key *key, void *buf, pj_size_t len)
- {
- return pj_ioqueue_read(this->ioq_(), key, buf, len);
- }
-
- int recvfrom(Key *key, void *buf, pj_size_t len, pj_sockaddr_t *addr, int *addrlen)
- {
- return pj_ioqueue_recvfrom(this->ioq_(), key, buf, len, addr, addrlen);
- }
-
- int write(Key *key, const void *data, pj_size_t len)
- {
- return pj_ioqueue_write(this->ioq_(), key, data, len);
- }
-
- int sendto(Key *key, const void *data, pj_size_t len, const pj_sockaddr_t *addr, int addrlen)
- {
- return pj_ioqueue_sendto(this->ioq_(), key, data, len, addr, addrlen);
- }
-};
-
-#endif /* __PJPP_IOQUEUE_H__ */
diff --git a/pjlib/include/pj++/list.hpp b/pjlib/include/pj++/list.hpp
index 68076785..9895c1c2 100644
--- a/pjlib/include/pj++/list.hpp
+++ b/pjlib/include/pj++/list.hpp
@@ -1,164 +1,290 @@
/* $Id$
- *
*/
#ifndef __PJPP_LIST_H__
#define __PJPP_LIST_H__
#include <pj/list.h>
-
-template <typename T>
-struct PJ_List_Node
-{
- PJ_DECL_LIST_MEMBER(T)
-};
-
-
-template <class Node>
-class PJ_List
+#include <pj++/pool.hpp>
+
+
+//
+// Linked-list.
+//
+// Note:
+// List_Node must have public member next and prev. Normally
+// it will be declared like:
+//
+// struct my_node
+// {
+// PJ_DECL_LIST_MEMBER(struct my_node);
+// ..
+// };
+//
+//
+template <class List_Node>
+class Pj_List : public Pj_Object
{
public:
- PJ_List() { pj_list_init(&root_); if (0) compiletest(); }
- ~PJ_List() {}
-
+ //
+ // List const_iterator.
+ //
class const_iterator
{
public:
- const_iterator() : node_(NULL) {}
- const_iterator(const Node *nd) : node_((Node*)nd) {}
- const Node * operator *() { return node_; }
- const Node * operator -> () { return node_; }
- const_iterator operator++() { return const_iterator(node_->next); }
- bool operator==(const const_iterator &rhs) { return node_ == rhs.node_; }
- bool operator!=(const const_iterator &rhs) { return node_ != rhs.node_; }
+ const_iterator()
+ : node_(NULL)
+ {}
+ const_iterator(const List_Node *nd)
+ : node_((List_Node*)nd)
+ {}
+ const List_Node * operator *()
+ {
+ return node_;
+ }
+ const List_Node * operator -> ()
+ {
+ return node_;
+ }
+ const_iterator operator++()
+ {
+ return const_iterator(node_->next);
+ }
+ bool operator==(const const_iterator &rhs)
+ {
+ return node_ == rhs.node_;
+ }
+ bool operator!=(const const_iterator &rhs)
+ {
+ return node_ != rhs.node_;
+ }
protected:
- Node *node_;
+ List_Node *node_;
};
+ //
+ // List iterator.
+ //
class iterator : public const_iterator
{
public:
- iterator() {}
- iterator(Node *nd) : const_iterator(nd) {}
- Node * operator *() { return node_; }
- Node * operator -> () { return node_; }
- iterator operator++() { return iterator(node_->next); }
- bool operator==(const iterator &rhs) { return node_ == rhs.node_; }
- bool operator!=(const iterator &rhs) { return node_ != rhs.node_; }
+ iterator()
+ {}
+ iterator(List_Node *nd)
+ : const_iterator(nd)
+ {}
+ List_Node * operator *()
+ {
+ return node_;
+ }
+ List_Node * operator -> ()
+ {
+ return node_;
+ }
+ iterator operator++()
+ {
+ return iterator(node_->next);
+ }
+ bool operator==(const iterator &rhs)
+ {
+ return node_ == rhs.node_;
+ }
+ bool operator!=(const iterator &rhs)
+ {
+ return node_ != rhs.node_;
+ }
};
+ //
+ // Default constructor.
+ //
+ Pj_List()
+ {
+ pj_list_init(&root_);
+ if (0) compiletest();
+ }
+
+ //
+ // Check if list is empty.
+ //
bool empty() const
{
return pj_list_empty(&root_);
}
+ //
+ // Get first element.
+ //
iterator begin()
{
return iterator(root_.next);
}
+ //
+ // Get first element.
+ //
const_iterator begin() const
{
return const_iterator(root_.next);
}
+ //
+ // Get end-of-element
+ //
const_iterator end() const
{
- return const_iterator((Node*)&root_);
+ return const_iterator((List_Node*)&root_);
}
+ //
+ // Get end-of-element
+ //
iterator end()
{
- return iterator((Node*)&root_);
+ return iterator((List_Node*)&root_);
}
- void insert_before (iterator &pos, Node *node)
+ //
+ // Insert node.
+ //
+ void insert_before (iterator &pos, List_Node *node)
{
pj_list_insert_before( *pos, node );
}
- void insert_after(iterator &pos, Node *node)
+ //
+ // Insert node.
+ //
+ void insert_after(iterator &pos, List_Node *node)
{
pj_list_insert_after(*pos, node);
}
- void merge_first(Node *list2)
+ //
+ // Merge list.
+ //
+ void merge_first(List_Node *list2)
{
pj_list_merge_first(&root_, list2);
}
- void merge_last(PJ_List *list)
+ //
+ // Merge list.
+ //
+ void merge_last(Pj_List *list)
{
pj_list_merge_last(&root_, &list->root_);
}
- void insert_nodes_before(iterator &pos, PJ_List *list2)
+ //
+ // Insert list.
+ //
+ void insert_nodes_before(iterator &pos, Pj_List *list2)
{
pj_list_insert_nodes_before(*pos, &list2->root_);
}
- void insert_nodes_after(iterator &pos, PJ_List *list2)
+ //
+ // Insert list.
+ //
+ void insert_nodes_after(iterator &pos, Pj_List *list2)
{
pj_list_insert_nodes_after(*pos, &list2->root_);
}
+ //
+ // Erase an element.
+ //
void erase(iterator &it)
{
pj_list_erase(*it);
}
- Node *front()
+ //
+ // Get first element.
+ //
+ List_Node *front()
{
return root_.next;
}
- const Node *front() const
+ //
+ // Get first element.
+ //
+ const List_Node *front() const
{
return root_.next;
}
+ //
+ // Remove first element.
+ //
void pop_front()
{
pj_list_erase(root_.next);
}
- Node *back()
+ //
+ // Get last element.
+ //
+ List_Node *back()
{
return root_.prev;
}
- const Node *back() const
+ //
+ // Get last element.
+ //
+ const List_Node *back() const
{
return root_.prev;
}
+ //
+ // Remove last element.
+ //
void pop_back()
{
pj_list_erase(root_.prev);
}
- iterator find(Node *node)
+ //
+ // Find a node.
+ //
+ iterator find(List_Node *node)
{
- Node *n = pj_list_find_node(&root_, node);
+ List_Node *n = pj_list_find_node(&root_, node);
return n ? iterator(n) : end();
}
- const_iterator find(Node *node) const
+ //
+ // Find a node.
+ //
+ const_iterator find(List_Node *node) const
{
- Node *n = pj_list_find_node(&root_, node);
+ List_Node *n = pj_list_find_node(&root_, node);
return n ? const_iterator(n) : end();
}
- void push_back(Node *node)
+ //
+ // Insert a node in the back.
+ //
+ void push_back(List_Node *node)
{
pj_list_insert_after(root_.prev, node);
}
- void push_front(Node *node)
+ //
+ // Insert a node in the front.
+ //
+ void push_front(List_Node *node)
{
pj_list_insert_before(root_.next, node);
}
+ //
+ // Remove all elements.
+ //
void clear()
{
root_.next = &root_;
@@ -168,14 +294,14 @@ public:
private:
struct RootNode
{
- PJ_DECL_LIST_MEMBER(Node)
+ PJ_DECL_LIST_MEMBER(List_Node);
} root_;
void compiletest()
{
// If you see error in this line,
- // it's because Node is not derived from PJ_List_Node.
- Node *n = (Node*)0;
+ // it's because List_Node is not derived from Pj_List_Node.
+ List_Node *n = (List_Node*)0;
n = n->next; n = n->prev;
}
};
diff --git a/pjlib/include/pj++/lock.hpp b/pjlib/include/pj++/lock.hpp
new file mode 100644
index 00000000..93a435e6
--- /dev/null
+++ b/pjlib/include/pj++/lock.hpp
@@ -0,0 +1,131 @@
+/* $Id$ */
+#ifndef __PJPP_LOCK_H__
+#define __PJPP_LOCK_H__
+
+#include <pj++/types.hpp>
+#include <pj/lock.h>
+#include <pj++/pool.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// Lock object.
+//
+class Pj_Lock : public Pj_Object
+{
+public:
+ //
+ // Constructor.
+ //
+ explicit Pj_Lock(pj_lock_t *lock)
+ : lock_(lock)
+ {
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Lock()
+ {
+ if (lock_)
+ pj_lock_destroy(lock_);
+ }
+
+ //
+ // Get pjlib compatible lock object.
+ //
+ pj_lock_t *pj_lock_t_()
+ {
+ return lock_;
+ }
+
+ //
+ // acquire lock.
+ //
+ pj_status_t acquire()
+ {
+ return pj_lock_acquire(lock_);
+ }
+
+ //
+ // release lock,.
+ //
+ pj_status_t release()
+ {
+ return pj_lock_release(lock_);
+ }
+
+protected:
+ pj_lock_t *lock_;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Null lock object.
+//
+class Pj_Null_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Null_Lock(Pj_Pool *pool, const char *name = NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_null_mutex(pool->pool_(), name, &lock_);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Simple mutex lock object.
+//
+class Pj_Simple_Mutex_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Simple_Mutex_Lock(Pj_Pool *pool, const char *name = NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_simple_mutex(pool->pool_(), name, &lock_);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Recursive mutex lock object.
+//
+class Pj_Recursive_Mutex_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Recursive_Mutex_Lock(Pj_Pool *pool, const char *name = NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_recursive_mutex(pool->pool_(), name, &lock_);
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Semaphore lock object.
+//
+class Pj_Semaphore_Lock : public Pj_Lock
+{
+public:
+ //
+ // Default constructor.
+ //
+ explicit Pj_Semaphore_Lock(Pj_Pool *pool,
+ unsigned max=PJ_MAXINT32,
+ unsigned initial=0,
+ const char *name=NULL)
+ : Pj_Lock(NULL)
+ {
+ pj_lock_create_semaphore(pool->pool_(), name, initial, max, &lock_);
+ }
+};
+
+
+
+#endif /* __PJPP_LOCK_H__ */
+
diff --git a/pjlib/include/pj++/os.hpp b/pjlib/include/pj++/os.hpp
index af89ac87..1101daea 100644
--- a/pjlib/include/pj++/os.hpp
+++ b/pjlib/include/pj++/os.hpp
@@ -1,5 +1,4 @@
/* $Id$
- *
*/
#ifndef __PJPP_OS_H__
#define __PJPP_OS_H__
@@ -8,142 +7,402 @@
#include <pj++/types.hpp>
#include <pj++/pool.hpp>
-class PJ_Thread
+class Pj_Thread;
+
+//
+// Thread API.
+//
+class Pj_Thread_API
{
public:
- enum Flags
+ //
+ // Create a thread.
+ //
+ static pj_status_t create( Pj_Pool *pool, pj_thread_t **thread,
+ pj_thread_proc *proc, void *arg,
+ unsigned flags = 0,
+ const char *name = NULL,
+ pj_size_t stack_size = 0 )
{
- FLAG_SUSPENDED = PJ_THREAD_SUSPENDED
- };
+ return pj_thread_create(pool->pool_(), name, proc, arg, stack_size,
+ flags, thread);
+ }
- static PJ_Thread *create( PJ_Pool *pool, const char *thread_name,
- pj_thread_proc *proc, void *arg,
- pj_size_t stack_size, void *stack_ptr,
- unsigned flags)
+ //
+ // Register a thread.
+ //
+ static pj_status_t register_this_thread( pj_thread_desc desc,
+ pj_thread_t **thread,
+ const char *name = NULL )
{
- return (PJ_Thread*) pj_thread_create( pool->pool_(), thread_name, proc, arg, stack_size, stack_ptr, flags);
+ return pj_thread_register( name, desc, thread );
}
- static PJ_Thread *register_current_thread(const char *name, pj_thread_desc desc)
+ //
+ // Get current thread.
+ // Will return pj_thread_t (sorry folks, not Pj_Thread).
+ //
+ static pj_thread_t *this_thread()
{
- return (PJ_Thread*) pj_thread_register(name, desc);
+ return pj_thread_this();
}
- static PJ_Thread *get_current_thread()
+ //
+ // Get thread name.
+ //
+ static const char *get_name(pj_thread_t *thread)
{
- return (PJ_Thread*) pj_thread_this();
+ return pj_thread_get_name(thread);
}
+ //
+ // Resume thread.
+ //
+ static pj_status_t resume(pj_thread_t *thread)
+ {
+ return pj_thread_resume(thread);
+ }
+
+ //
+ // Sleep.
+ //
static pj_status_t sleep(unsigned msec)
{
return pj_thread_sleep(msec);
}
- static pj_status_t usleep(unsigned usec)
+ //
+ // Join the specified thread.
+ //
+ static pj_status_t join(pj_thread_t *thread)
+ {
+ return pj_thread_join(thread);
+ }
+
+ //
+ // Destroy thread
+ //
+ static pj_status_t destroy(pj_thread_t *thread)
+ {
+ return pj_thread_destroy(thread);
+ }
+};
+
+
+
+//
+// Thread object.
+//
+// How to use:
+// Derive a class from this class, then override main().
+//
+class Pj_Thread : public Pj_Object
+{
+public:
+ enum Flags
+ {
+ FLAG_SUSPENDED = PJ_THREAD_SUSPENDED
+ };
+
+ //
+ // Default constructor.
+ //
+ Pj_Thread()
+ : thread_(NULL)
{
- return pj_thread_usleep(usec);
}
+ //
+ // Destroy thread.
+ //
+ ~Pj_Thread()
+ {
+ destroy();
+ }
+
+ //
+ // This is the main thread function.
+ //
+ virtual int main() = 0;
+
+ //
+ // Start a thread.
+ //
+ pj_status_t create( Pj_Pool *pool,
+ unsigned flags = 0,
+ const char *thread_name = NULL,
+ pj_size_t stack_size = PJ_THREAD_DEFAULT_STACK_SIZE)
+ {
+ destroy();
+ return Pj_Thread_API::create( pool, &thread_, &thread_proc, this,
+ flags, thread_name);
+ }
+
+ //
+ // Get pjlib compatible thread object.
+ //
pj_thread_t *pj_thread_t_()
{
- return (pj_thread_t*)this;
+ return thread_;
}
+ //
+ // Get thread name.
+ //
const char *get_name()
{
- return pj_thread_get_name( this->pj_thread_t_() );
+ return Pj_Thread_API::get_name(thread_);
}
+ //
+ // Resume a suspended thread.
+ //
pj_status_t resume()
{
- return pj_thread_resume( this->pj_thread_t_() );
+ return Pj_Thread_API::resume(thread_);
}
+ //
+ // Join this thread.
+ //
pj_status_t join()
{
- return pj_thread_join( this->pj_thread_t_() );
+ return Pj_Thread_API::join(thread_);
}
+ //
+ // Destroy thread.
+ //
pj_status_t destroy()
{
- return pj_thread_destroy( this->pj_thread_t_() );
+ if (thread_) {
+ Pj_Thread_API::destroy(thread_);
+ thread_ = NULL;
+ }
+ }
+
+protected:
+ pj_thread_t *thread_;
+
+ static int PJ_THREAD_FUNC thread_proc(void *obj)
+ {
+ Pj_Thread *thread_class = (Pj_Thread*)obj;
+ return thread_class->main();
}
};
-class PJ_Thread_Local
+//
+// External Thread
+// (threads that were started by external means, i.e. not
+// with Pj_Thread::create).
+//
+// This class will normally be defined as local variable in
+// external thread's stack, normally inside thread's main proc.
+// But be aware that the handle will be destroyed on destructor!
+//
+class Pj_External_Thread : public Pj_Thread
{
public:
- static PJ_Thread_Local *alloc()
+ Pj_External_Thread()
{
- long index = pj_thread_local_alloc();
- return index < 0 ? NULL : (PJ_Thread_Local*)index;
}
- void free()
+
+ //
+ // Register external thread so that pjlib functions can work
+ // in that thread.
+ //
+ pj_status_t register_this_thread( const char *name=NULL )
{
- pj_thread_local_free( this->tls_() );
+ return Pj_Thread_API::register_this_thread(desc_, &thread_,name);
}
- long tls_() const
+private:
+ pj_thread_desc desc_;
+};
+
+
+//
+// Thread specific data/thread local storage/TLS.
+//
+class Pj_Thread_Local_API
+{
+public:
+ //
+ // Allocate thread local storage (TLS) index.
+ //
+ static pj_status_t alloc(long *index)
{
- return (long)this;
+ return pj_thread_local_alloc(index);
}
- void set(void *value)
+ //
+ // Free TLS index.
+ //
+ static void free(long index)
{
- pj_thread_local_set( this->tls_(), value );
+ pj_thread_local_free(index);
}
- void *get()
+ //
+ // Set thread specific data.
+ //
+ static pj_status_t set(long index, void *value)
{
- return pj_thread_local_get( this->tls_() );
+ return pj_thread_local_set(index, value);
+ }
+
+ //
+ // Get thread specific data.
+ //
+ static void *get(long index)
+ {
+ return pj_thread_local_get(index);
}
-};
+};
-class PJ_Atomic
+//
+// Atomic variable
+//
+// How to use:
+// Pj_Atomic_Var var(pool, 0);
+// var.set(..);
+//
+class Pj_Atomic_Var : public Pj_Object
{
public:
- static PJ_Atomic *create(PJ_Pool *pool, long initial)
+ //
+ // Default constructor, initialize variable with NULL.
+ //
+ Pj_Atomic_Var()
+ : var_(NULL)
+ {
+ }
+
+ //
+ // Construct atomic variable.
+ //
+ Pj_Atomic_Var(Pj_Pool *pool, pj_atomic_value_t value)
+ : var_(NULL)
{
- return (PJ_Atomic*) pj_atomic_create(pool->pool_(), initial);
+ create(pool, value);
}
+ //
+ // Destructor.
+ //
+ ~Pj_Atomic_Var()
+ {
+ destroy();
+ }
+
+ //
+ // Create atomic variable.
+ //
+ pj_status_t create( Pj_Pool *pool, pj_atomic_value_t value)
+ {
+ destroy();
+ return pj_atomic_create(pool->pool_(), value, &var_);
+ }
+
+ //
+ // Destroy.
+ //
+ void destroy()
+ {
+ if (var_) {
+ pj_atomic_destroy(var_);
+ var_ = NULL;
+ }
+ }
+
+ //
+ // Get pjlib compatible atomic variable.
+ //
pj_atomic_t *pj_atomic_t_()
{
- return (pj_atomic_t*)this;
+ return var_;
}
- pj_status_t destroy()
+ //
+ // Set the value.
+ //
+ void set(pj_atomic_value_t val)
+ {
+ pj_atomic_set(var_, val);
+ }
+
+ //
+ // Get the value.
+ //
+ pj_atomic_value_t get()
{
- return pj_atomic_destroy( this->pj_atomic_t_() );
+ return pj_atomic_get(var_);
}
- long set(long val)
+ //
+ // Increment.
+ //
+ void inc()
{
- return pj_atomic_set( this->pj_atomic_t_(), val);
+ pj_atomic_inc(var_);
}
- long get()
+ //
+ // Increment and get the result.
+ //
+ pj_atomic_value_t inc_and_get()
{
- return pj_atomic_get( this->pj_atomic_t_() );
+ return pj_atomic_inc_and_get(var_);
}
- long inc()
+ //
+ // Decrement.
+ //
+ void dec()
{
- return pj_atomic_inc( this->pj_atomic_t_() );
+ pj_atomic_dec(var_);
}
- long dec()
+ //
+ // Decrement and get the result.
+ //
+ pj_atomic_value_t dec_and_get()
{
- return pj_atomic_dec( this->pj_atomic_t_() );
+ return pj_atomic_dec_and_get(var_);
}
+
+ //
+ // Add the variable.
+ //
+ void add(pj_atomic_value_t value)
+ {
+ pj_atomic_add(var_, value);
+ }
+
+ //
+ // Add the variable and get the value.
+ //
+ pj_atomic_value_t add_and_get(pj_atomic_value_t value)
+ {
+ return pj_atomic_add_and_get(var_, value );
+ }
+
+private:
+ pj_atomic_t *var_;
};
-class PJ_Mutex
+//
+// Mutex
+//
+class Pj_Mutex : public Pj_Object
{
public:
+ //
+ // Mutex type.
+ //
enum Type
{
DEFAULT = PJ_MUTEX_DEFAULT,
@@ -151,194 +410,378 @@ public:
RECURSE = PJ_MUTEX_RECURSE,
};
- static PJ_Mutex *create( PJ_Pool *pool, const char *name, Type type)
+ //
+ // Default constructor will create default mutex.
+ //
+ explicit Pj_Mutex(Pj_Pool *pool, Type type = DEFAULT,
+ const char *name = NULL)
+ : mutex_(NULL)
{
- return (PJ_Mutex*) pj_mutex_create( pool->pool_(), name, type);
+ create(pool, type, name);
}
- pj_mutex_t *pj_mutex_()
+ //
+ // Destructor.
+ //
+ ~Pj_Mutex()
{
- return (pj_mutex_t*)this;
+ destroy();
}
- pj_status_t destroy()
+ //
+ // Create mutex.
+ //
+ pj_status_t create( Pj_Pool *pool, Type type, const char *name = NULL)
+ {
+ destroy();
+ return pj_mutex_create( pool->pool_(), name, type,
+ &mutex_ );
+ }
+
+ //
+ // Create simple mutex.
+ //
+ pj_status_t create_simple( Pj_Pool *pool,const char *name = NULL)
+ {
+ return create(pool, SIMPLE, name);
+ }
+
+ //
+ // Create recursive mutex.
+ //
+ pj_status_t create_recursive( Pj_Pool *pool, const char *name = NULL )
{
- return pj_mutex_destroy( this->pj_mutex_() );
+ return create(pool, RECURSE, name);
}
- pj_status_t lock()
+ //
+ // Get pjlib compatible mutex object.
+ //
+ pj_mutex_t *pj_mutex_t_()
{
- return pj_mutex_lock( this->pj_mutex_() );
+ return mutex_;
}
- pj_status_t unlock()
+ //
+ // Destroy mutex.
+ //
+ void destroy()
{
- return pj_mutex_unlock( this->pj_mutex_() );
+ if (mutex_) {
+ pj_mutex_destroy(mutex_);
+ mutex_ = NULL;
+ }
}
- pj_status_t trylock()
+ //
+ // Lock mutex.
+ //
+ pj_status_t acquire()
{
- return pj_mutex_trylock( this->pj_mutex_() );
+ return pj_mutex_lock(mutex_);
}
-#if PJ_DEBUG
- pj_status_t is_locked()
+ //
+ // Unlock mutex.
+ //
+ pj_status_t release()
{
- return pj_mutex_is_locked( this->pj_mutex_() );
+ return pj_mutex_unlock(mutex_);
}
-#endif
+
+ //
+ // Try locking the mutex.
+ //
+ pj_status_t tryacquire()
+ {
+ return pj_mutex_trylock(mutex_);
+ }
+
+private:
+ pj_mutex_t *mutex_;
};
-class PJ_Semaphore
+//
+// Semaphore
+//
+class Pj_Semaphore : public Pj_Object
{
public:
- static PJ_Semaphore *create( PJ_Pool *pool, const char *name, unsigned initial, unsigned max)
+ //
+ // Construct semaphore
+ //
+ Pj_Semaphore(Pj_Pool *pool, unsigned max,
+ unsigned initial = 0, const char *name = NULL)
+ : sem_(NULL)
{
- return (PJ_Semaphore*) pj_sem_create( pool->pool_(), name, initial, max);
}
- pj_sem_t *pj_sem_t_()
+ //
+ // Destructor.
+ //
+ ~Pj_Semaphore()
{
- return (pj_sem_t*)this;
+ destroy();
}
- pj_status_t destroy()
+ //
+ // Create semaphore
+ //
+ pj_status_t create( Pj_Pool *pool, unsigned max,
+ unsigned initial = 0, const char *name = NULL )
{
- return pj_sem_destroy(this->pj_sem_t_());
+ destroy();
+ return pj_sem_create( pool->pool_(), name, initial, max, &sem_);
}
+ //
+ // Destroy semaphore.
+ //
+ void destroy()
+ {
+ if (sem_) {
+ pj_sem_destroy(sem_);
+ sem_ = NULL;
+ }
+ }
+
+ //
+ // Get pjlib compatible semaphore object.
+ //
+ pj_sem_t *pj_sem_t_()
+ {
+ return (pj_sem_t*)this;
+ }
+
+ //
+ // Wait semaphore.
+ //
pj_status_t wait()
{
return pj_sem_wait(this->pj_sem_t_());
}
- pj_status_t lock()
+ //
+ // Wait semaphore.
+ //
+ pj_status_t acquire()
{
return wait();
}
+ //
+ // Try wait semaphore.
+ //
pj_status_t trywait()
{
return pj_sem_trywait(this->pj_sem_t_());
}
- pj_status_t trylock()
+ //
+ // Try wait semaphore.
+ //
+ pj_status_t tryacquire()
{
return trywait();
}
+ //
+ // Post semaphore.
+ //
pj_status_t post()
{
return pj_sem_post(this->pj_sem_t_());
}
- pj_status_t unlock()
+ //
+ // Post semaphore.
+ //
+ pj_status_t release()
{
return post();
}
+
+private:
+ pj_sem_t *sem_;
};
-class PJ_Event
+//
+// Event object.
+//
+class Pj_Event
{
public:
- static PJ_Event *create( PJ_Pool *pool, const char *name, bool manual_reset, bool initial)
+ //
+ // Construct event object.
+ //
+ Pj_Event( Pj_Pool *pool, bool manual_reset = false,
+ bool initial = false, const char *name = NULL )
+ : event_(NULL)
+ {
+ create(pool, manual_reset, initial, name);
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Event()
{
- return (PJ_Event*) pj_event_create(pool->pool_(), name, manual_reset, initial);
+ destroy();
}
+ //
+ // Create event object.
+ //
+ pj_status_t create( Pj_Pool *pool, bool manual_reset = false,
+ bool initial = false, const char *name = NULL)
+ {
+ destroy();
+ return pj_event_create(pool->pool_(), name, manual_reset, initial,
+ &event_);
+ }
+
+ //
+ // Get pjlib compatible event object.
+ //
pj_event_t *pj_event_t_()
{
- return (pj_event_t*)this;
+ return event_;
}
- pj_status_t destroy()
+ //
+ // Destroy event object.
+ //
+ void destroy()
{
- return pj_event_destroy(this->pj_event_t_());
+ if (event_) {
+ pj_event_destroy(event_);
+ event_ = NULL;
+ }
}
+ //
+ // Wait.
+ //
pj_status_t wait()
{
- return pj_event_wait(this->pj_event_t_());
+ return pj_event_wait(event_);
}
+ //
+ // Try wait.
+ //
pj_status_t trywait()
{
- return pj_event_trywait(this->pj_event_t_());
+ return pj_event_trywait(event_);
}
+ //
+ // Set event state to signalled.
+ //
pj_status_t set()
{
return pj_event_set(this->pj_event_t_());
}
+ //
+ // Release one waiting thread.
+ //
pj_status_t pulse()
{
return pj_event_pulse(this->pj_event_t_());
}
+ //
+ // Set a non-signalled.
+ //
pj_status_t reset()
{
return pj_event_reset(this->pj_event_t_());
}
+
+private:
+ pj_event_t *event_;
};
-class PJ_OS
+//
+// OS abstraction.
+//
+class Pj_OS_API
{
public:
- static pj_status_t gettimeofday( PJ_Time_Val *tv )
+ //
+ // Get current time.
+ //
+ static pj_status_t gettimeofday( Pj_Time_Val *tv )
{
return pj_gettimeofday(tv);
}
- static pj_status_t time_decode( const PJ_Time_Val *tv, pj_parsed_time *pt )
+ //
+ // Parse to time of day.
+ //
+ static pj_status_t time_decode( const Pj_Time_Val *tv,
+ pj_parsed_time *pt )
{
return pj_time_decode(tv, pt);
}
- static pj_status_t time_encode(const pj_parsed_time *pt, PJ_Time_Val *tv)
+ //
+ // Parse from time of day.
+ //
+ static pj_status_t time_encode( const pj_parsed_time *pt,
+ Pj_Time_Val *tv)
{
return pj_time_encode(pt, tv);
}
- static pj_status_t time_local_to_gmt( PJ_Time_Val *tv )
+ //
+ // Convert to GMT.
+ //
+ static pj_status_t time_local_to_gmt( Pj_Time_Val *tv )
{
return pj_time_local_to_gmt( tv );
}
- static pj_status_t time_gmt_to_local( PJ_Time_Val *tv)
+ //
+ // Convert time to local.
+ //
+ static pj_status_t time_gmt_to_local( Pj_Time_Val *tv)
{
return pj_time_gmt_to_local( tv );
}
};
-
-inline pj_status_t PJ_Time_Val::gettimeofday()
+//
+// Timeval inlines.
+//
+inline pj_status_t Pj_Time_Val::gettimeofday()
{
- return PJ_OS::gettimeofday(this);
+ return Pj_OS_API::gettimeofday(this);
}
-inline pj_parsed_time PJ_Time_Val::decode()
+inline pj_parsed_time Pj_Time_Val::decode()
{
pj_parsed_time pt;
- PJ_OS::time_decode(this, &pt);
+ Pj_OS_API::time_decode(this, &pt);
return pt;
}
-inline pj_status_t PJ_Time_Val::encode(const pj_parsed_time *pt)
+inline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt)
{
- return PJ_OS::time_encode(pt, this);
+ return Pj_OS_API::time_encode(pt, this);
}
-inline pj_status_t PJ_Time_Val::to_gmt()
+inline pj_status_t Pj_Time_Val::to_gmt()
{
- return PJ_OS::time_local_to_gmt(this);
+ return Pj_OS_API::time_local_to_gmt(this);
}
-inline pj_status_t PJ_Time_Val::to_local()
+inline pj_status_t Pj_Time_Val::to_local()
{
- return PJ_OS::time_gmt_to_local(this);
+ return Pj_OS_API::time_gmt_to_local(this);
}
#endif /* __PJPP_OS_H__ */
diff --git a/pjlib/include/pj++/pool.hpp b/pjlib/include/pj++/pool.hpp
index d2af77bb..611cd7a7 100644
--- a/pjlib/include/pj++/pool.hpp
+++ b/pjlib/include/pj++/pool.hpp
@@ -1,86 +1,244 @@
/* $Id$
- *
*/
#ifndef __PJPP_POOL_H__
#define __PJPP_POOL_H__
#include <pj/pool.h>
-class PJ_Pool
+class Pj_Pool;
+class Pj_Caching_Pool;
+
+//
+// Base class for all Pjlib objects
+//
+class Pj_Object
+{
+public:
+ void *operator new(unsigned int class_size, Pj_Pool *pool);
+ void operator delete(void*);
+ void operator delete(void*, Pj_Pool*);
+
+ //
+ // Inline implementations at the end of this file.
+ //
+
+private:
+ // Can not use normal new operator; must use pool.
+ // e.g.:
+ // obj = new(pool) Pj_The_Object(pool, ...);
+ //
+ void *operator new(unsigned int)
+ {}
+};
+
+
+//
+// Pool.
+//
+class Pj_Pool : public Pj_Object
{
public:
+ //
+ // Default constructor, initializes internal pool to NULL.
+ // Application must call attach() some time later.
+ //
+ Pj_Pool()
+ : p_(NULL)
+ {
+ }
+
+ //
+ // Create pool.
+ //
+ Pj_Pool(Pj_Caching_Pool &caching_pool,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ const char *name = NULL,
+ pj_pool_callback *callback = NULL);
+
+ //
+ // Construct from existing pool.
+ //
+ explicit Pj_Pool(pj_pool_t *pool)
+ : p_(pool)
+ {
+ }
+
+ //
+ // Attach existing pool.
+ //
+ void attach(pj_pool_t *pool)
+ {
+ p_ = pool;
+ }
+
+ //
+ // Destructor.
+ //
+ // Release pool back to factory. Remember: if you delete pool, then
+ // make sure that all objects that have been allocated from this pool
+ // have been properly destroyed.
+ //
+ // This is where C++ is trickier than plain C!!
+ //
+ ~Pj_Pool()
+ {
+ if (p_)
+ pj_pool_release(p_);
+ }
+
+ //
+ // Get name.
+ //
const char *getobjname() const
{
- return pj_pool_getobjname(this->pool_());
+ return pj_pool_getobjname(p_);
}
+ //
+ // Get pjlib compatible pool object.
+ //
pj_pool_t *pool_()
{
- return (pj_pool_t*)this;
+ return p_;
}
+ //
+ // Get pjlib compatible pool object.
+ //
const pj_pool_t *pool_() const
{
- return (const pj_pool_t*)this;
+ return p_;
}
- void release()
+ //
+ // Get pjlib compatible pool object.
+ //
+ pj_pool_t *pj_pool_t_()
{
- pj_pool_release(this->pool_());
+ return p_;
}
+ //
+ // Reset pool.
+ //
void reset()
{
- pj_pool_reset(this->pool_());
+ pj_pool_reset(p_);
}
+ //
+ // Get current capacity.
+ //
pj_size_t get_capacity()
{
- pj_pool_get_capacity(this->pool_());
+ pj_pool_get_capacity(p_);
}
+ //
+ // Get current total bytes allocated from the pool.
+ //
pj_size_t get_used_size()
{
- pj_pool_get_used_size(this->pool_());
+ pj_pool_get_used_size(p_);
}
+ //
+ // Allocate.
+ //
void *alloc(pj_size_t size)
{
- return pj_pool_alloc(this->pool_(), size);
+ return pj_pool_alloc(p_, size);
}
+ //
+ // Allocate elements and zero fill the memory.
+ //
void *calloc(pj_size_t count, pj_size_t elem)
{
- return pj_pool_calloc(this->pool_(), count, elem);
+ return pj_pool_calloc(p_, count, elem);
}
+
+ //
+ // Allocate and zero fill memory.
+ //
+ void *zalloc(pj_size_t size)
+ {
+ return pj_pool_zalloc(p_, size);
+ }
+
+private:
+ pj_pool_t *p_;
};
-class PJ_Caching_Pool
+
+//
+// Caching pool.
+//
+class Pj_Caching_Pool
{
public:
- void init(pj_size_t max_capacity,
- const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy)
+ //
+ // Construct caching pool.
+ //
+ Pj_Caching_Pool( pj_size_t cache_capacity = 0,
+ const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy)
{
- pj_caching_pool_init(&cp_, pol, max_capacity);
+ pj_caching_pool_init(&cp_, pol, cache_capacity);
}
- void destroy()
+ //
+ // Destroy caching pool.
+ //
+ ~Pj_Caching_Pool()
{
pj_caching_pool_destroy(&cp_);
}
- PJ_Pool *create_pool(const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback)
+ //
+ // Create pool.
+ //
+ pj_pool_t *create_pool( pj_size_t initial_size,
+ pj_size_t increment_size,
+ const char *name = NULL,
+ pj_pool_callback *callback = NULL)
{
- return (PJ_Pool*) (*cp_.factory.create_pool)(&cp_.factory, name, initial_size, increment_size, callback);
- }
-
- void release_pool( PJ_Pool *pool )
- {
- pj_pool_release(pool->pool_());
+ return (pj_pool_t*)(*cp_.factory.create_pool)(&cp_.factory, name,
+ initial_size,
+ increment_size,
+ callback);
}
private:
pj_caching_pool cp_;
};
+//
+// Inlines for Pj_Object
+//
+inline void *Pj_Object::operator new(unsigned int class_size, Pj_Pool *pool)
+{
+ return pool->alloc(class_size);
+}
+inline void Pj_Object::operator delete(void *ptr)
+{
+}
+inline void Pj_Object::operator delete(void *ptr, Pj_Pool*)
+{
+}
+
+//
+// Inlines for Pj_Pool
+//
+inline Pj_Pool::Pj_Pool( Pj_Caching_Pool &caching_pool,
+ pj_size_t initial_size,
+ pj_size_t increment_size,
+ const char *name,
+ pj_pool_callback *callback)
+{
+ p_ = caching_pool.create_pool(initial_size, increment_size, name,
+ callback);
+}
+
+
#endif /* __PJPP_POOL_H__ */
diff --git a/pjlib/include/pj++/proactor.hpp b/pjlib/include/pj++/proactor.hpp
index cae9cf43..7021a5a0 100644
--- a/pjlib/include/pj++/proactor.hpp
+++ b/pjlib/include/pj++/proactor.hpp
@@ -1,88 +1,481 @@
/* $Id$
- *
*/
-#ifndef __PJPP_EVENT_HANDLER_H__
-#define __PJPP_EVENT_HANDLER_H__
+#ifndef __PJPP_PROACTOR_H__
+#define __PJPP_PROACTOR_H__
#include <pj/ioqueue.h>
#include <pj++/pool.hpp>
#include <pj++/sock.hpp>
#include <pj++/timer.hpp>
+#include <pj/errno.h>
-class PJ_Proactor;
+class Pj_Proactor;
+class Pj_Event_Handler;
-class PJ_Event_Handler
+//////////////////////////////////////////////////////////////////////////////
+// Asynchronous operation key.
+//
+// Applications may inheric this class to put their application
+// specific data.
+//
+class Pj_Async_Op : public pj_ioqueue_op_key_t
{
- friend class PJ_Proactor;
public:
- PJ_Event_Handler();
- virtual ~PJ_Event_Handler();
+ //
+ // Constructor.
+ //
+ explicit Pj_Async_Op(Pj_Event_Handler *handler)
+ : handler_(handler)
+ {
+ pj_memset(this, 0, sizeof(pj_ioqueue_op_key_t));
+ }
+
+ //
+ // Check whether operation is still pending for this key.
+ //
+ bool is_pending();
+
+ //
+ // Cancel the operation.
+ //
+ bool cancel(pj_ssize_t bytes_status=-PJ_ECANCELLED);
+
+protected:
+ Pj_Event_Handler *handler_;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Event handler.
+//
+// Applications should inherit this class to receive various event
+// notifications.
+//
+// Applications should implement get_socket_handle().
+//
+class Pj_Event_Handler : public Pj_Object
+{
+ friend class Pj_Proactor;
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Event_Handler()
+ : key_(NULL)
+ {
+ pj_memset(&timer_, 0, sizeof(timer_));
+ timer_.user_data = this;
+ timer_.cb = &timer_callback;
+ }
+
+ //
+ // Destroy.
+ //
+ virtual ~Pj_Event_Handler()
+ {
+ unregister();
+ }
+
+ //
+ // Unregister this handler from the ioqueue.
+ //
+ void unregister()
+ {
+ if (key_) {
+ pj_ioqueue_unregister(key_);
+ key_ = NULL;
+ }
+ }
+
+ //
+ // Get socket handle associated with this.
+ //
+ virtual pj_sock_t get_socket_handle()
+ {
+ return PJ_INVALID_SOCKET;
+ }
+
+ //
+ // Receive data.
+ //
+ pj_status_t recv( Pj_Async_Op *op_key,
+ void *buf, pj_ssize_t *len,
+ unsigned flags)
+ {
+ return pj_ioqueue_recv( key_, op_key,
+ buf, len, flags);
+ }
+
+ //
+ // Recvfrom()
+ //
+ pj_status_t recvfrom( Pj_Async_Op *op_key,
+ void *buf, pj_ssize_t *len, unsigned flags,
+ Pj_Inet_Addr *addr)
+ {
+ addr->addrlen_ = sizeof(Pj_Inet_Addr);
+ return pj_ioqueue_recvfrom( key_, op_key, buf, len, flags,
+ addr, &addr->addrlen_ );
+ }
- virtual pj_oshandle_t get_handle() = 0;
+ //
+ // send()
+ //
+ pj_status_t send( Pj_Async_Op *op_key,
+ const void *data, pj_ssize_t *len,
+ unsigned flags)
+ {
+ return pj_ioqueue_send( key_, op_key, data, len, flags);
+ }
+
+ //
+ // sendto()
+ //
+ pj_status_t sendto( Pj_Async_Op *op_key,
+ const void *data, pj_ssize_t *len, unsigned flags,
+ const Pj_Inet_Addr &addr)
+ {
+ return pj_ioqueue_sendto(key_, op_key, data, len, flags,
+ &addr, sizeof(addr));
+ }
- bool read(void *buf, pj_size_t len);
- bool recvfrom(void *buf, pj_size_t len, PJ_INET_Addr *addr);
- bool write(const void *data, pj_size_t len);
- bool sendto(const void *data, pj_size_t len, const PJ_INET_Addr &addr);
#if PJ_HAS_TCP
- bool connect(const PJ_INET_Addr &addr);
- bool accept(PJ_Socket *sock, PJ_INET_Addr *local=NULL, PJ_INET_Addr *remote=NULL);
+ //
+ // connect()
+ //
+ pj_status_t connect(const Pj_Inet_Addr &addr)
+ {
+ return pj_ioqueue_connect(key_, &addr, sizeof(addr));
+ }
+
+ //
+ // accept.
+ //
+ pj_status_t accept( Pj_Async_Op *op_key,
+ Pj_Socket *sock,
+ Pj_Inet_Addr *local = NULL,
+ Pj_Inet_Addr *remote = NULL)
+ {
+ int *addrlen = local ? &local->addrlen_ : NULL;
+ return pj_ioqueue_accept( key_, op_key, &sock->sock_,
+ local, remote, addrlen );
+ }
+
#endif
protected:
- //
+ //////////////////
// Overridables
+ //////////////////
+
+ //
+ // Timeout callback.
+ //
+ virtual void on_timeout(int data)
+ {
+ }
+
//
- virtual void on_timeout(int data) {}
- virtual void on_read_complete(pj_ssize_t bytes_read) {}
- virtual void on_write_complete(pj_ssize_t bytes_sent) {}
+ // On read complete callback.
+ //
+ virtual void on_read_complete( Pj_Async_Op *op_key,
+ pj_ssize_t bytes_read)
+ {
+ }
+
+ //
+ // On write complete callback.
+ //
+ virtual void on_write_complete( Pj_Async_Op *op_key,
+ pj_ssize_t bytes_sent)
+ {
+ }
+
#if PJ_HAS_TCP
- virtual void on_connect_complete(int status) {}
- virtual void on_accept_complete(int status) {}
+ //
+ // On connect complete callback.
+ //
+ virtual void on_connect_complete(pj_status_t status)
+ {
+ }
+
+ //
+ // On new connection callback.
+ //
+ virtual void on_accept_complete( Pj_Async_Op *op_key,
+ pj_sock_t new_sock,
+ pj_status_t status)
+ {
+ }
+
#endif
+
private:
- PJ_Proactor *proactor_;
pj_ioqueue_key_t *key_;
pj_timer_entry timer_;
- int tmp_recvfrom_addr_len;
-public:
- // Internal IO Queue/timer callback.
- static void timer_callback( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry);
- static void read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read);
- static void write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent);
- static void accept_complete_cb(pj_ioqueue_key_t *key, int status);
- static void connect_complete_cb(pj_ioqueue_key_t *key, int status);
+ friend class Pj_Proactor;
+ friend class Pj_Async_Op;
+
+ //
+ // Static timer callback.
+ //
+ static void timer_callback( pj_timer_heap_t *timer_heap,
+ struct pj_timer_entry *entry)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) entry->user_data;
+
+ handler->on_timeout(entry->id);
+ }
};
-class PJ_Proactor
+inline bool Pj_Async_Op::is_pending()
+{
+ return pj_ioqueue_is_pending(handler_->key_, this) != 0;
+}
+
+inline bool Pj_Async_Op::cancel(pj_ssize_t bytes_status)
+{
+ return pj_ioqueue_post_completion(handler_->key_, this,
+ bytes_status) == PJ_SUCCESS;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Proactor
+//
+class Pj_Proactor : public Pj_Object
{
public:
- static PJ_Proactor *create(PJ_Pool *pool, pj_size_t max_fd,
- pj_size_t timer_entry_count, unsigned timer_flags=0);
+ //
+ // Default constructor, initializes to NULL.
+ //
+ Pj_Proactor()
+ : ioq_(NULL), th_(NULL)
+ {
+ cb_.on_read_complete = &read_complete_cb;
+ cb_.on_write_complete = &write_complete_cb;
+ cb_.on_accept_complete = &accept_complete_cb;
+ cb_.on_connect_complete = &connect_complete_cb;
+ }
+
+ //
+ // Construct proactor.
+ //
+ Pj_Proactor( Pj_Pool *pool, pj_size_t max_fd,
+ pj_size_t max_timer_entries )
+ : ioq_(NULL), th_(NULL)
+ {
+ cb_.on_read_complete = &read_complete_cb;
+ cb_.on_write_complete = &write_complete_cb;
+ cb_.on_accept_complete = &accept_complete_cb;
+ cb_.on_connect_complete = &connect_complete_cb;
+ }
+
+ //
+ // Destructor.
+ //
+ ~Pj_Proactor()
+ {
+ destroy();
+ }
+
+ //
+ // Create proactor.
+ //
+ pj_status_t create( Pj_Pool *pool, pj_size_t max_fd,
+ pj_size_t timer_entry_count)
+ {
+ pj_status_t status;
+
+ destroy();
+
+ status = pj_ioqueue_create(pool->pool_(), max_fd, &ioq_);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pj_timer_heap_create(pool->pool_(),
+ timer_entry_count, &th_);
+ if (status != PJ_SUCCESS) {
+ pj_ioqueue_destroy(ioq_);
+ ioq_ = NULL;
+ return NULL;
+ }
+
+ status;
+ }
+
+ //
+ // Destroy proactor.
+ //
+ void destroy()
+ {
+ if (ioq_) {
+ pj_ioqueue_destroy(ioq_);
+ ioq_ = NULL;
+ }
+ if (th_) {
+ pj_timer_heap_destroy(th_);
+ th_ = NULL;
+ }
+ }
+
+ //
+ // Register handler.
+ // This will call handler->get_socket_handle()
+ //
+ pj_status_t register_socket_handler(Pj_Pool *pool,
+ Pj_Event_Handler *handler)
+ {
+ return pj_ioqueue_register_sock( pool->pool_(), ioq_,
+ handler->get_socket_handle(),
+ handler, &cb_, &handler->key_ );
+ }
+
+ //
+ // Unregister handler.
+ //
+ static void unregister_handler(Pj_Event_Handler *handler)
+ {
+ if (handler->key_) {
+ pj_ioqueue_unregister( handler->key_ );
+ handler->key_ = NULL;
+ }
+ }
+
+ //
+ // Scheduler timer.
+ //
+ bool schedule_timer( Pj_Event_Handler *handler,
+ const Pj_Time_Val &delay,
+ int id=-1)
+ {
+ return schedule_timer(th_, handler, delay, id);
+ }
- void destroy();
+ //
+ // Cancel timer.
+ //
+ bool cancel_timer(Pj_Event_Handler *handler)
+ {
+ return pj_timer_heap_cancel(th_, &handler->timer_) == 1;
+ }
+
+ //
+ // Handle events.
+ //
+ int handle_events(Pj_Time_Val *max_timeout)
+ {
+ Pj_Time_Val timeout(0, 0);
+ int timer_count;
+
+ timer_count = pj_timer_heap_poll( th_, &timeout );
+
+ if (timeout.get_sec() < 0)
+ timeout.sec = PJ_MAXINT32;
+
+ /* If caller specifies maximum time to wait, then compare the value
+ * with the timeout to wait from timer, and use the minimum value.
+ */
+ if (max_timeout && timeout >= *max_timeout) {
+ timeout = *max_timeout;
+ }
- bool register_handler(PJ_Pool *pool, PJ_Event_Handler *handler);
- void unregister_handler(PJ_Event_Handler *handler);
+ /* Poll events in ioqueue. */
+ int ioqueue_count;
- static bool schedule_timer( pj_timer_heap_t *timer, PJ_Event_Handler *handler,
- const PJ_Time_Val &delay, int id=-1);
- bool schedule_timer(PJ_Event_Handler *handler, const PJ_Time_Val &delay, int id=-1);
- bool cancel_timer(PJ_Event_Handler *handler);
+ ioqueue_count = pj_ioqueue_poll(ioq_, &timeout);
+ if (ioqueue_count < 0)
+ return ioqueue_count;
- bool handle_events(PJ_Time_Val *timeout);
+ return ioqueue_count + timer_count;
+ }
- pj_ioqueue_t *get_io_queue();
- pj_timer_heap_t *get_timer_heap();
+ //
+ // Get the internal ioqueue object.
+ //
+ pj_ioqueue_t *get_io_queue()
+ {
+ return ioq_;
+ }
+
+ //
+ // Get the internal timer heap object.
+ //
+ pj_timer_heap_t *get_timer_heap()
+ {
+ return th_;
+ }
private:
pj_ioqueue_t *ioq_;
pj_timer_heap_t *th_;
+ pj_ioqueue_callback cb_;
+
+ static bool schedule_timer( pj_timer_heap_t *timer,
+ Pj_Event_Handler *handler,
+ const Pj_Time_Val &delay,
+ int id=-1)
+ {
+ handler->timer_.id = id;
+ return pj_timer_heap_schedule(timer, &handler->timer_, &delay) == 0;
+ }
+
+
+ //
+ // Static read completion callback.
+ //
+ static void read_complete_cb( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_read_complete((Pj_Async_Op*)op_key, bytes_read);
+ }
+
+ //
+ // Static write completion callback.
+ //
+ static void write_complete_cb(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_sent)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_write_complete((Pj_Async_Op*)op_key, bytes_sent);
+ }
+
+ //
+ // Static accept completion callback.
+ //
+ static void accept_complete_cb(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_sock_t new_sock,
+ pj_status_t status)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_accept_complete((Pj_Async_Op*)op_key, new_sock, status);
+ }
+
+ //
+ // Static connect completion callback.
+ //
+ static void connect_complete_cb(pj_ioqueue_key_t *key,
+ pj_status_t status)
+ {
+ Pj_Event_Handler *handler =
+ (Pj_Event_Handler*) pj_ioqueue_get_user_data(key);
+
+ handler->on_connect_complete(status);
+ }
- PJ_Proactor() {}
};
-#endif /* __PJPP_EVENT_HANDLER_H__ */
+#endif /* __PJPP_PROACTOR_H__ */
diff --git a/pjlib/include/pj++/scanner.hpp b/pjlib/include/pj++/scanner.hpp
index 80ac0a8b..9ddac097 100644
--- a/pjlib/include/pj++/scanner.hpp
+++ b/pjlib/include/pj++/scanner.hpp
@@ -4,13 +4,13 @@
#ifndef __PJPP_SCANNER_H__
#define __PJPP_SCANNER_H__
-#include <pj/scanner.h>
+#include <pjlib-util/scanner.h>
#include <pj++/string.hpp>
-class PJ_CharSpec
+class Pj_Char_Spec
{
public:
- PJ_CharSpec() { pj_cs_init(cs__); }
+ Pj_Char_Spec() { pj_cs_init(cs__); }
void set(int c) { pj_cs_set(cs__, c); }
void add_range(int begin, int end) { pj_cs_add_range(cs__, begin, end); }
@@ -36,10 +36,10 @@ private:
pj_char_spec cs__;
};
-class PJ_Scanner
+class Pj_Scanner
{
public:
- PJ_Scanner() {}
+ Pj_Scanner() {}
enum
{
@@ -67,30 +67,30 @@ public:
int peek_char() const
{
- return *scanner_.current;
+ return *scanner_.curptr;
}
- int peek(const PJ_CharSpec *cs, PJ_String *out)
+ int peek(const Pj_Char_Spec *cs, Pj_String *out)
{
return pj_scan_peek(&scanner_, cs->cs_(), out);
}
- int peek_n(pj_size_t len, PJ_String *out)
+ int peek_n(pj_size_t len, Pj_String *out)
{
return pj_scan_peek_n(&scanner_, len, out);
}
- int peek_until(const PJ_CharSpec *cs, PJ_String *out)
+ int peek_until(const Pj_Char_Spec *cs, Pj_String *out)
{
return pj_scan_peek_until(&scanner_, cs->cs_(), out);
}
- void get(const PJ_CharSpec *cs, PJ_String *out)
+ void get(const Pj_Char_Spec *cs, Pj_String *out)
{
pj_scan_get(&scanner_, cs->cs_(), out);
}
- void get_n(unsigned N, PJ_String *out)
+ void get_n(unsigned N, Pj_String *out)
{
pj_scan_get_n(&scanner_, N, out);
}
@@ -100,7 +100,7 @@ public:
return pj_scan_get_char(&scanner_);
}
- void get_quote(int begin_quote, int end_quote, PJ_String *out)
+ void get_quote(int begin_quote, int end_quote, Pj_String *out)
{
pj_scan_get_quote(&scanner_, begin_quote, end_quote, out);
}
@@ -110,17 +110,17 @@ public:
pj_scan_get_newline(&scanner_);
}
- void get_until(const PJ_CharSpec *cs, PJ_String *out)
+ void get_until(const Pj_Char_Spec *cs, Pj_String *out)
{
pj_scan_get_until(&scanner_, cs->cs_(), out);
}
- void get_until_ch(int until_ch, PJ_String *out)
+ void get_until_ch(int until_ch, Pj_String *out)
{
pj_scan_get_until_ch(&scanner_, until_ch, out);
}
- void get_until_chr(const char *spec, PJ_String *out)
+ void get_until_chr(const char *spec, Pj_String *out)
{
pj_scan_get_until_chr(&scanner_, spec, out);
}
diff --git a/pjlib/include/pj++/sock.hpp b/pjlib/include/pj++/sock.hpp
index a38fd22d..1c6c2dd9 100644
--- a/pjlib/include/pj++/sock.hpp
+++ b/pjlib/include/pj++/sock.hpp
@@ -1,196 +1,426 @@
/* $Id$
- *
*/
#ifndef __PJPP_SOCK_H__
#define __PJPP_SOCK_H__
#include <pj/sock.h>
+#include <pj/string.h>
-class PJ_Addr
+class Pj_Event_Handler;
+
+//
+// Base class for address.
+//
+class Pj_Addr
{
};
-class PJ_INET_Addr : public pj_sockaddr_in, public PJ_Addr
+//
+// Internet address.
+//
+class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr
{
public:
+ //
+ // Get port number.
+ //
pj_uint16_t get_port_number() const
{
- return pj_sockaddr_get_port(this);
+ return pj_sockaddr_in_get_port(this);
}
+ //
+ // Set port number.
+ //
void set_port_number(pj_uint16_t port)
{
sin_family = PJ_AF_INET;
- pj_sockaddr_set_port(this, port);
+ pj_sockaddr_in_set_port(this, port);
}
+ //
+ // Get IP address.
+ //
pj_uint32_t get_ip_address() const
{
- return pj_sockaddr_get_addr(this);
+ return pj_sockaddr_in_get_addr(this).s_addr;
}
+ //
+ // Get address string.
+ //
const char *get_address() const
{
- return pj_sockaddr_get_str_addr(this);
+ return pj_inet_ntoa(sin_addr);
}
+ //
+ // Set IP address.
+ //
void set_ip_address(pj_uint32_t addr)
{
sin_family = PJ_AF_INET;
- pj_sockaddr_set_addr(this, addr);
+ pj_sockaddr_in_set_addr(this, addr);
}
+ //
+ // Set address.
+ //
pj_status_t set_address(const pj_str_t *addr)
{
- return pj_sockaddr_set_str_addr(this, addr);
+ return pj_sockaddr_in_set_str_addr(this, addr);
}
+ //
+ // Set address.
+ //
pj_status_t set_address(const char *addr)
{
- return pj_sockaddr_set_str_addr2(this, addr);
+ pj_str_t s;
+ return pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr));
}
- int cmp(const PJ_INET_Addr &rhs) const
+ //
+ // Compare for equality.
+ //
+ bool operator==(const Pj_Inet_Addr &rhs) const
{
- return pj_sockaddr_cmp(this, &rhs);
+ return sin_family == rhs.sin_family &&
+ sin_addr.s_addr == rhs.sin_addr.s_addr &&
+ sin_port == rhs.sin_port;
}
- bool operator==(const PJ_INET_Addr &rhs) const
- {
- return cmp(rhs) == 0;
- }
+private:
+ //
+ // Dummy length used in pj_ioqueue_recvfrom() etc
+ //
+ friend class Pj_Event_Handler;
+ friend class Pj_Socket;
+ friend class Pj_Sock_Stream;
+ friend class Pj_Sock_Dgram;
+
+ int addrlen_;
};
-class PJ_Socket
+
+//
+// Socket base class.
+//
+// Note:
+// socket will not automatically be closed on destructor.
+//
+class Pj_Socket
{
public:
- PJ_Socket() {}
- PJ_Socket(const PJ_Socket &rhs) : sock_(rhs.sock_) {}
+ //
+ // Default constructor.
+ //
+ Pj_Socket()
+ : sock_(PJ_INVALID_SOCKET)
+ {
+ }
+ //
+ // Initialize from a socket handle.
+ //
+ explicit Pj_Socket(pj_sock_t sock)
+ : sock_(sock)
+ {
+ }
+
+ //
+ // Copy constructor.
+ //
+ Pj_Socket(const Pj_Socket &rhs)
+ : sock_(rhs.sock_)
+ {
+ }
+
+ //
+ // Destructor will not close the socket.
+ // You must call close() explicitly.
+ //
+ ~Pj_Socket()
+ {
+ }
+
+ //
+ // Set socket handle.
+ //
void set_handle(pj_sock_t sock)
{
sock_ = sock;
}
+ //
+ // Get socket handle.
+ //
pj_sock_t get_handle() const
{
return sock_;
}
+ //
+ // Get socket handle.
+ //
pj_sock_t& get_handle()
{
return sock_;
}
- bool socket(int af, int type, int proto, pj_uint32_t flag=0)
+ //
+ // See if the socket is valid.
+ //
+ bool is_valid() const
{
- sock_ = pj_sock_socket(af, type, proto, flag);
- return sock_ != -1;
+ return sock_ != PJ_INVALID_SOCKET;
}
- bool bind(const PJ_INET_Addr &addr)
+ //
+ // Create the socket.
+ //
+ pj_status_t create(int af, int type, int proto)
{
- return pj_sock_bind(sock_, &addr, sizeof(PJ_INET_Addr)) == 0;
+ return pj_sock_socket(af, type, proto, &sock_);
}
- bool close()
+ //
+ // Bind socket.
+ //
+ pj_status_t bind(const Pj_Inet_Addr &addr)
{
- return pj_sock_close(sock_) == 0;
+ return pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr));
}
- bool getpeername(PJ_INET_Addr *addr)
+ //
+ // Close socket.
+ //
+ pj_status_t close()
{
- int namelen;
- return pj_sock_getpeername(sock_, addr, &namelen) == 0;
+ pj_sock_close(sock_);
}
- bool getsockname(PJ_INET_Addr *addr)
+ //
+ // Get peer socket name.
+ //
+ pj_status_t getpeername(Pj_Inet_Addr *addr)
{
- int namelen;
- return pj_sock_getsockname(sock_, addr, &namelen) == 0;
+ return pj_sock_getpeername(sock_, addr, &addr->addrlen_);
}
- bool getsockopt(int level, int optname, void *optval, int *optlen)
+ //
+ // getsockname
+ //
+ pj_status_t getsockname(Pj_Inet_Addr *addr)
{
- return pj_sock_getsockopt(sock_, level, optname, optval, optlen) == 0;
+ return pj_sock_getsockname(sock_, addr, &addr->addrlen_);
}
- bool setsockopt(int level, int optname, const void *optval, int optlen)
+ //
+ // getsockopt.
+ //
+ pj_status_t getsockopt(int level, int optname,
+ void *optval, int *optlen)
{
- return pj_sock_setsockopt(sock_, level, optname, optval, optlen) == 0;
+ return pj_sock_getsockopt(sock_, level, optname, optval, optlen);
}
- bool ioctl(long cmd, pj_uint32_t *val)
+ //
+ // setsockopt
+ //
+ pj_status_t setsockopt(int level, int optname,
+ const void *optval, int optlen)
{
- return pj_sock_ioctl(sock_, cmd, val) == 0;
+ return pj_sock_setsockopt(sock_, level, optname, optval, optlen);
}
- int recv(void *buf, int len, int flag = 0)
+ //
+ // receive data.
+ //
+ pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0)
{
- return pj_sock_recv(sock_, buf, len, flag);
+ pj_ssize_t bytes = len;
+ if (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS)
+ return -1;
+ return bytes;
}
- int send(const void *buf, int len, int flag = 0)
+ //
+ // send data.
+ //
+ pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0)
{
- return pj_sock_send(sock_, buf, len, flag);
+ pj_ssize_t bytes = len;
+ if (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS)
+ return -1;
+ return bytes;
+ }
+
+ //
+ // connect.
+ //
+ pj_status_t connect(const Pj_Inet_Addr &addr)
+ {
+ return pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr));
+ }
+
+ //
+ // assignment.
+ //
+ Pj_Socket &operator=(const Pj_Socket &rhs)
+ {
+ sock_ = rhs.sock_;
+ return *this;
}
protected:
+ friend class Pj_Event_Handler;
pj_sock_t sock_;
};
+
#if PJ_HAS_TCP
-class PJ_Sock_Stream : public PJ_Socket
+//
+// Stream socket.
+//
+class Pj_Sock_Stream : public Pj_Socket
{
public:
- PJ_Sock_Stream() {}
- PJ_Sock_Stream(const PJ_Sock_Stream &rhs) : PJ_Socket(rhs) {}
- PJ_Sock_Stream &operator=(const PJ_Sock_Stream &rhs) { sock_ = rhs.sock_; return *this; }
+ //
+ // Default constructor.
+ //
+ Pj_Sock_Stream()
+ {
+ }
+
+ //
+ // Initialize from a socket handle.
+ //
+ explicit Pj_Sock_Stream(pj_sock_t sock)
+ : Pj_Socket(sock)
+ {
+ }
- bool listen(int backlog = 5)
+ //
+ // Copy constructor.
+ //
+ Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs)
{
- return pj_sock_listen(sock_, backlog) == 0;
}
- bool accept(PJ_Sock_Stream *new_sock, PJ_INET_Addr *addr, int *addrlen)
+ //
+ // Assignment.
+ //
+ Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs)
+ {
+ sock_ = rhs.sock_;
+ return *this;
+ }
+
+ //
+ // listen()
+ //
+ pj_status_t listen(int backlog = 5)
{
- pj_sock_t s = pj_sock_accept(sock_, addr, addrlen);
- if (s == -1)
- return false;
- new_sock->set_handle(s);
- return true;
+ return pj_sock_listen(sock_, backlog);
}
- bool connect(const PJ_INET_Addr &addr)
+ //
+ // blocking accept()
+ //
+ Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL)
{
- return pj_sock_connect(sock_, &addr, sizeof(PJ_INET_Addr)) == 0;
+ pj_sock_t newsock;
+ int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL;
+ pj_status_t status;
+
+ status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen);
+ if (status != PJ_SUCCESS)
+ return Pj_Sock_Stream(-1);
+
+ return Pj_Sock_Stream(newsock);
}
- bool shutdown(int how)
+ //
+ // shutdown()
+ //
+ pj_status_t shutdown(int how = PJ_SHUT_RDWR)
{
- return pj_sock_shutdown(sock_, how) == 0;
+ return pj_sock_shutdown(sock_, how);
}
};
#endif
-class PJ_Sock_Dgram : public PJ_Socket
+//
+// Datagram socket.
+//
+class Pj_Sock_Dgram : public Pj_Socket
{
public:
- PJ_Sock_Dgram() {}
- PJ_Sock_Dgram(const PJ_Sock_Dgram &rhs) : PJ_Socket(rhs) {}
- PJ_Sock_Dgram &operator=(const PJ_Sock_Dgram &rhs) { sock_ = rhs.sock_; return *this; }
+ //
+ // Default constructor.
+ //
+ Pj_Sock_Dgram()
+ {
+ }
+
+ //
+ // Initialize from a socket handle.
+ //
+ explicit Pj_Sock_Dgram(pj_sock_t sock)
+ : Pj_Socket(sock)
+ {
+ }
+
+ //
+ // Copy constructor.
+ //
+ Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs)
+ : Pj_Socket(rhs)
+ {
+ }
- int recvfrom(void *buf, int len, int flag, PJ_INET_Addr *fromaddr)
+ //
+ // Assignment.
+ //
+ Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs)
+ {
+ Pj_Socket::operator =(rhs);
+ return *this;
+ }
+
+ //
+ // recvfrom()
+ //
+ pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0,
+ Pj_Inet_Addr *fromaddr = NULL)
{
- int addrlen;
- return pj_sock_recvfrom(sock_, buf, len, flag, fromaddr, &addrlen);
+ pj_ssize_t bytes = len;
+ int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL;
+ if (pj_sock_recvfrom( sock_, buf, &bytes, flag,
+ fromaddr, addrlen) != PJ_SUCCESS)
+ {
+ return -1;
+ }
+ return bytes;
}
- int sendto(const void *buf, int len, int flag, const PJ_INET_Addr &addr)
+ //
+ // sendto()
+ //
+ pj_ssize_t sendto( const void *buf, pj_size_t len, int flag,
+ const Pj_Inet_Addr &addr)
{
- return pj_sock_sendto(sock_, buf, len, flag, &addr, sizeof(PJ_INET_Addr));
+ pj_ssize_t bytes = len;
+ if (pj_sock_sendto( sock_, buf, &bytes, flag,
+ &addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS)
+ {
+ return -1;
+ }
+ return bytes;
}
};
+
#endif /* __PJPP_SOCK_H__ */
diff --git a/pjlib/include/pj++/string.hpp b/pjlib/include/pj++/string.hpp
index d55e737b..456e1ff3 100644
--- a/pjlib/include/pj++/string.hpp
+++ b/pjlib/include/pj++/string.hpp
@@ -1,249 +1,408 @@
/* $Id$
- *
*/
#ifndef __PJPP_STRING_H__
#define __PJPP_STRING_H__
#include <pj/string.h>
#include <pj++/pool.hpp>
+#include <pj/assert.h>
-class PJ_String : public pj_str_t
+//
+// String wrapper class for pj_str_t.
+//
+class Pj_String : public pj_str_t
{
public:
- PJ_String()
+ //
+ // Default constructor.
+ //
+ Pj_String()
{
- pj_assert(sizeof(PJ_String) == sizeof(pj_str_t));
- ptr=NULL; slen=0;
+ pj_assert(sizeof(Pj_String) == sizeof(pj_str_t));
+ ptr=NULL;
+ slen=0;
}
- explicit PJ_String(char *str)
+ //
+ // Construct the buffer from a char*.
+ //
+ explicit Pj_String(char *str)
{
set(str);
}
- PJ_String(PJ_Pool *pool, const char *src)
+ //
+ // Construct from a const char*.
+ //
+ Pj_String(Pj_Pool *pool, const char *src)
{
set(pool, src);
}
- explicit PJ_String(pj_str_t *s)
+ //
+ // Construct from pj_str_t*.
+ //
+ explicit Pj_String(pj_str_t *s)
{
set(s);
}
- PJ_String(PJ_Pool *pool, const pj_str_t *s)
+ //
+ // Construct by copying from const pj_str_t*.
+ //
+ Pj_String(Pj_Pool *pool, const pj_str_t *s)
{
set(pool, s);
}
- explicit PJ_String(PJ_String &rhs)
+ //
+ // Construct from another Pj_String
+ //
+ explicit Pj_String(Pj_String &rhs)
{
set(rhs);
}
- PJ_String(PJ_Pool *pool, const PJ_String &rhs)
+ //
+ // Construct by copying from Pj_String
+ //
+ Pj_String(Pj_Pool *pool, const Pj_String &rhs)
{
set(pool, rhs);
}
- PJ_String(char *str, pj_size_t len)
+ //
+ // Construct from a char* and a length.
+ //
+ Pj_String(char *str, pj_size_t len)
{
set(str, len);
}
- PJ_String(char *begin, char *end)
+ //
+ // Construct from pair of pointer.
+ //
+ Pj_String(char *begin, char *end)
{
pj_strset3(this, begin, end);
}
+ //
+ // Get the length of the string.
+ //
pj_size_t length() const
{
return pj_strlen(this);
}
+ //
+ // Get the length of the string.
+ //
pj_size_t size() const
{
return length();
}
+ //
+ // Get the string buffer.
+ //
const char *buf() const
{
return ptr;
}
+ //
+ // Initialize buffer from char*.
+ //
void set(char *str)
{
pj_strset2(this, str);
}
- void set(PJ_Pool *pool, const char *s)
+ //
+ // Initialize by copying from a const char*.
+ //
+ void set(Pj_Pool *pool, const char *s)
{
pj_strdup2(pool->pool_(), this, s);
}
+ //
+ // Initialize from pj_str_t*.
+ //
void set(pj_str_t *s)
{
pj_strassign(this, s);
}
- void set(PJ_Pool *pool, const pj_str_t *s)
+ //
+ // Initialize by copying from const pj_str_t*.
+ //
+ void set(Pj_Pool *pool, const pj_str_t *s)
{
pj_strdup(pool->pool_(), this, s);
}
+ //
+ // Initialize from char* and length.
+ //
void set(char *str, pj_size_t len)
{
pj_strset(this, str, len);
}
+ //
+ // Initialize from pair of pointers.
+ //
void set(char *begin, char *end)
{
pj_strset3(this, begin, end);
}
- void set(PJ_String &rhs)
+ //
+ // Initialize from other Pj_String.
+ //
+ void set(Pj_String &rhs)
{
pj_strassign(this, &rhs);
}
- void set(PJ_Pool *pool, const PJ_String *s)
+ //
+ // Initialize by copying from a Pj_String*.
+ //
+ void set(Pj_Pool *pool, const Pj_String *s)
{
pj_strdup(pool->pool_(), this, s);
}
- void set(PJ_Pool *pool, const PJ_String &s)
+ //
+ // Initialize by copying from other Pj_String.
+ //
+ void set(Pj_Pool *pool, const Pj_String &s)
{
pj_strdup(pool->pool_(), this, &s);
}
+ //
+ // Copy the contents of other string.
+ //
void strcpy(const pj_str_t *s)
{
pj_strcpy(this, s);
}
- void strcpy(const PJ_String &rhs)
+ //
+ // Copy the contents of other string.
+ //
+ void strcpy(const Pj_String &rhs)
{
pj_strcpy(this, &rhs);
}
+ //
+ // Copy the contents of other string.
+ //
void strcpy(const char *s)
{
pj_strcpy2(this, s);
}
+ //
+ // Compare string.
+ //
int strcmp(const char *s) const
{
return pj_strcmp2(this, s);
}
+ //
+ // Compare string.
+ //
int strcmp(const pj_str_t *s) const
{
return pj_strcmp(this, s);
}
- int strcmp(const PJ_String &rhs) const
+ //
+ // Compare string.
+ //
+ int strcmp(const Pj_String &rhs) const
{
return pj_strcmp(this, &rhs);
}
+ //
+ // Compare string.
+ //
int strncmp(const char *s, pj_size_t len) const
{
return pj_strncmp2(this, s, len);
}
+ //
+ // Compare string.
+ //
int strncmp(const pj_str_t *s, pj_size_t len) const
{
return pj_strncmp(this, s, len);
}
- int strncmp(const PJ_String &rhs, pj_size_t len) const
+ //
+ // Compare string.
+ //
+ int strncmp(const Pj_String &rhs, pj_size_t len) const
{
return pj_strncmp(this, &rhs, len);
}
+ //
+ // Compare string.
+ //
int stricmp(const char *s) const
{
return pj_stricmp2(this, s);
}
+ //
+ // Compare string.
+ //
int stricmp(const pj_str_t *s) const
{
return pj_stricmp(this, s);
}
- int stricmp(const PJ_String &rhs) const
+ //
+ // Compare string.
+ //
+ int stricmp(const Pj_String &rhs) const
{
return stricmp(&rhs);
}
+ //
+ // Compare string.
+ //
int strnicmp(const char *s, pj_size_t len) const
{
return pj_strnicmp2(this, s, len);
}
+ //
+ // Compare string.
+ //
int strnicmp(const pj_str_t *s, pj_size_t len) const
{
return pj_strnicmp(this, s, len);
}
- int strnicmp(const PJ_String &rhs, pj_size_t len) const
+ //
+ // Compare string.
+ //
+ int strnicmp(const Pj_String &rhs, pj_size_t len) const
{
return strnicmp(&rhs, len);
}
+ //
+ // Compare contents for equality.
+ //
bool operator==(const char *s) const
{
return strcmp(s) == 0;
}
+ //
+ // Compare contents for equality.
+ //
bool operator==(const pj_str_t *s) const
{
return strcmp(s) == 0;
}
- bool operator==(const PJ_String &rhs) const
+ //
+ // Compare contents for equality.
+ //
+ bool operator==(const Pj_String &rhs) const
{
return pj_strcmp(this, &rhs) == 0;
}
+ //
+ // Find a character in the string.
+ //
char *strchr(int chr)
{
return pj_strchr(this, chr);
}
+ //
+ // Find a character in the string.
+ //
char *find(int chr)
{
return strchr(chr);
}
- void strcat(const PJ_String &rhs)
+ //
+ // Concatenate string.
+ //
+ void strcat(const Pj_String &rhs)
{
pj_strcat(this, &rhs);
}
+ //
+ // Left trim.
+ //
void ltrim()
{
pj_strltrim(this);
}
+ //
+ // Right trim.
+ //
void rtrim()
{
pj_strrtrim(this);
}
+ //
+ // Left and right trim.
+ //
void trim()
{
pj_strtrim(this);
}
- unsigned long toul() const
+ //
+ // Convert to unsigned long.
+ //
+ unsigned long to_ulong() const
{
return pj_strtoul(this);
}
+ //
+ // Convert from unsigned long.
+ //
+ void from_ulong(unsigned long value)
+ {
+ slen = pj_utoa(value, ptr);
+ }
+
+ //
+ // Convert from unsigned long with padding.
+ //
+ void from_ulong_with_pad(unsigned long value, int min_dig=0, int pad=' ')
+ {
+ slen = pj_utoa_pad(value, ptr, min_dig, pad);
+ }
+
+
private:
- //PJ_String(const PJ_String &rhs) {}
- void operator=(const PJ_String &rhs) { pj_assert(false); }
+ //Pj_String(const Pj_String &rhs) {}
+ void operator=(const Pj_String &rhs) { pj_assert(false); }
};
#endif /* __PJPP_STRING_H__ */
diff --git a/pjlib/include/pj++/timer.hpp b/pjlib/include/pj++/timer.hpp
index 8357a198..b1070421 100644
--- a/pjlib/include/pj++/timer.hpp
+++ b/pjlib/include/pj++/timer.hpp
@@ -1,101 +1,174 @@
/* $Id$
- *
*/
#ifndef __PJPP_TIMER_H__
#define __PJPP_TIMER_H__
#include <pj/timer.h>
#include <pj++/types.hpp>
-
-class PJ_Timer_Heap;
-
-class PJ_Timer_Entry : private pj_timer_entry
+#include <pj/assert.h>
+#include <pj++/lock.hpp>
+
+class Pj_Timer_Heap;
+
+//////////////////////////////////////////////////////////////////////////////
+// Timer entry.
+//
+// How to use:
+// Derive class from Pj_Timer_Entry and override on_timeout().
+// Scheduler timer in Pj_Timer_Heap.
+//
+class Pj_Timer_Entry : public Pj_Object
{
- friend class PJ_Timer_Heap;
+ friend class Pj_Timer_Heap;
public:
- static void timer_heap_callback(pj_timer_heap_t *, pj_timer_entry *);
+ //
+ // Default constructor.
+ //
+ Pj_Timer_Entry()
+ {
+ entry_.user_data = this;
+ entry_.cb = &timer_heap_callback;
+ }
- PJ_Timer_Entry() { cb = &timer_heap_callback; }
- PJ_Timer_Entry(int arg_id, void *arg_user_data)
+ //
+ // Destructor, do nothing.
+ //
+ ~Pj_Timer_Entry()
{
- cb = &timer_heap_callback;
- init(arg_id, arg_user_data);
}
- virtual void on_timeout() = 0;
+ //
+ // Override this to get the timeout notification.
+ //
+ virtual void on_timeout(int id) = 0;
+
+private:
+ pj_timer_entry entry_;
- void init(int arg_id, void *arg_user_data)
+ static void timer_heap_callback(pj_timer_heap_t *th, pj_timer_entry *e)
{
- id = arg_id;
- user_data = arg_user_data;
+ Pj_Timer_Entry *entry = (Pj_Timer_Entry*) e->user_data;
+ entry->on_timeout(e->id);
}
- int get_id() const
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Timer heap.
+//
+class Pj_Timer_Heap : public Pj_Object
+{
+public:
+ //
+ // Default constructor.
+ //
+ Pj_Timer_Heap()
+ : ht_(NULL)
{
- return id;
}
- void set_id(int arg_id)
+ //
+ // Construct timer heap.
+ //
+ Pj_Timer_Heap(Pj_Pool *pool, pj_size_t initial_count)
+ : ht_(NULL)
{
- id = arg_id;
+ create(pool, initial_count);
}
- void set_user_data(void *arg_user_data)
+ //
+ // Destructor.
+ //
+ ~Pj_Timer_Heap()
{
- user_data = arg_user_data;
+ destroy();
}
- void *get_user_data() const
+ //
+ // Create
+ //
+ pj_status_t create(Pj_Pool *pool, pj_size_t initial_count)
{
- return user_data;
+ destroy();
+ return pj_timer_heap_create(pool->pool_(), initial_count, &ht_);
}
- const PJ_Time_Val &get_timeout() const
+ //
+ // Destroy
+ //
+ void destroy()
{
- pj_assert(sizeof(PJ_Time_Val) == sizeof(pj_time_val));
- return (PJ_Time_Val&)_timer_value;
+ if (ht_) {
+ pj_timer_heap_destroy(ht_);
+ ht_ = NULL;
+ }
}
-};
-class PJ_Timer_Heap
-{
-public:
- PJ_Timer_Heap() {}
+ //
+ // Get pjlib compatible timer heap object.
+ //
+ pj_timer_heap_t *get_timer_heap()
+ {
+ return ht_;
+ }
- bool create(PJ_Pool *pool, pj_size_t initial_count,
- unsigned flag = PJ_TIMER_HEAP_SYNCHRONIZE)
+ //
+ // Set the lock object.
+ //
+ void set_lock( Pj_Lock *lock, bool auto_delete )
{
- ht_ = pj_timer_heap_create(pool->pool_(), initial_count, flag);
- return ht_ != NULL;
+ pj_timer_heap_set_lock( ht_, lock->pj_lock_t_(), auto_delete);
}
- pj_timer_heap_t *get_timer_heap()
+ //
+ // Set maximum number of timed out entries to be processed per poll.
+ //
+ unsigned set_max_timed_out_per_poll(unsigned count)
{
- return ht_;
+ return pj_timer_heap_set_max_timed_out_per_poll(ht_, count);
}
- bool schedule( PJ_Timer_Entry *ent, const PJ_Time_Val &delay)
+ //
+ // Schedule a timer.
+ //
+ bool schedule( Pj_Timer_Entry *ent, const Pj_Time_Val &delay,
+ int id)
{
- return pj_timer_heap_schedule(ht_, ent, &delay) == 0;
+ ent->entry_.id = id;
+ return pj_timer_heap_schedule(ht_, &ent->entry_, &delay) == 0;
}
- bool cancel(PJ_Timer_Entry *ent)
+ //
+ // Cancel a timer.
+ //
+ bool cancel(Pj_Timer_Entry *ent)
{
- return pj_timer_heap_cancel(ht_, ent) == 1;
+ return pj_timer_heap_cancel(ht_, &ent->entry_) == 1;
}
+ //
+ // Get current number of timers
+ //
pj_size_t count()
{
return pj_timer_heap_count(ht_);
}
- void earliest_time(PJ_Time_Val *t)
+ //
+ // Get the earliest time.
+ // Return false if no timer is found.
+ //
+ bool earliest_time(Pj_Time_Val *t)
{
- pj_timer_heap_earliest_time(ht_, t);
+ return pj_timer_heap_earliest_time(ht_, t) == PJ_SUCCESS;
}
- int poll(PJ_Time_Val *next_delay = NULL)
+ //
+ // Poll the timer.
+ // Return number of timed out entries has been called.
+ //
+ unsigned poll(Pj_Time_Val *next_delay = NULL)
{
return pj_timer_heap_poll(ht_, next_delay);
}
diff --git a/pjlib/include/pj++/tree.hpp b/pjlib/include/pj++/tree.hpp
index db5e8d2a..7d30c678 100644
--- a/pjlib/include/pj++/tree.hpp
+++ b/pjlib/include/pj++/tree.hpp
@@ -6,6 +6,9 @@
#include <pj/rbtree.h>
+//
+// Tree.
+//
class PJ_Tree
{
public:
diff --git a/pjlib/include/pj++/types.hpp b/pjlib/include/pj++/types.hpp
index efa74399..637c1222 100644
--- a/pjlib/include/pj++/types.hpp
+++ b/pjlib/include/pj++/types.hpp
@@ -6,55 +6,138 @@
#include <pj/types.h>
-class PJ_Pool;
-class PJ_Socket;
+class Pj_Pool;
+class Pj_Socket ;
+class Pj_Lock;
-class PJ_Time_Val : public pj_time_val
+//
+// PJLIB initializer.
+//
+class Pjlib
{
public:
- PJ_Time_Val() {}
- PJ_Time_Val(const PJ_Time_Val &rhs) { sec=rhs.sec; msec=rhs.msec; }
- explicit PJ_Time_Val(const pj_time_val &tv) { sec = tv.sec; msec = tv.msec; }
-
- long get_sec() const { return sec; }
- long get_msec() const { return msec; }
- void set_sec (long s) { sec = s; }
- void set_msec(long ms) { msec = ms; normalize(); }
- long to_msec() const { return PJ_TIME_VAL_MSEC((*this)); }
-
- bool operator == (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_EQ((*this), rhs); }
- bool operator > (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_GT((*this), rhs); }
- bool operator >= (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_GTE((*this), rhs); }
- bool operator < (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_LT((*this), rhs); }
- bool operator <= (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_LTE((*this), rhs); }
-
- PJ_Time_Val & operator = (const PJ_Time_Val &rhs) {
+ Pjlib()
+ {
+ pj_init();
+ }
+};
+
+//
+// Class Pj_Object is declared in pool.hpp
+//
+
+//
+// Time value wrapper.
+//
+class Pj_Time_Val : public pj_time_val
+{
+public:
+ Pj_Time_Val()
+ {
+ }
+
+ Pj_Time_Val(long init_sec, long init_msec)
+ {
+ sec = init_sec;
+ msec = init_msec;
+ }
+
+ Pj_Time_Val(const Pj_Time_Val &rhs)
+ {
+ sec=rhs.sec;
+ msec=rhs.msec;
+ }
+
+ explicit Pj_Time_Val(const pj_time_val &tv)
+ {
+ sec = tv.sec;
+ msec = tv.msec;
+ }
+
+ long get_sec() const
+ {
+ return sec;
+ }
+
+ long get_msec() const
+ {
+ return msec;
+ }
+
+ void set_sec (long s)
+ {
+ sec = s;
+ }
+
+ void set_msec(long ms)
+ {
+ msec = ms;
+ normalize();
+ }
+
+ long to_msec() const
+ {
+ return PJ_TIME_VAL_MSEC((*this));
+ }
+
+ bool operator == (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_EQ((*this), rhs);
+ }
+
+ bool operator > (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_GT((*this), rhs);
+ }
+
+ bool operator >= (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_GTE((*this), rhs);
+ }
+
+ bool operator < (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_LT((*this), rhs);
+ }
+
+ bool operator <= (const Pj_Time_Val &rhs) const
+ {
+ return PJ_TIME_VAL_LTE((*this), rhs);
+ }
+
+ Pj_Time_Val & operator = (const Pj_Time_Val &rhs)
+ {
sec = rhs.sec;
msec = rhs.msec;
return *this;
}
- PJ_Time_Val & operator += (const PJ_Time_Val &rhs) {
+ Pj_Time_Val & operator += (const Pj_Time_Val &rhs)
+ {
PJ_TIME_VAL_ADD((*this), rhs);
return *this;
}
- PJ_Time_Val & operator -= (const PJ_Time_Val &rhs) {
+ Pj_Time_Val & operator -= (const Pj_Time_Val &rhs)
+ {
PJ_TIME_VAL_SUB((*this), rhs);
return *this;
}
/* Must include os.hpp to use these, otherwise unresolved in linking */
- pj_status_t gettimeofday();
- pj_parsed_time decode();
- pj_status_t encode(const pj_parsed_time *pt);
- pj_status_t to_gmt();
- pj_status_t to_local();
+ inline pj_status_t gettimeofday();
+ inline pj_parsed_time decode();
+ inline pj_status_t encode(const pj_parsed_time *pt);
+ inline pj_status_t to_gmt();
+ inline pj_status_t to_local();
private:
- void normalize() { pj_time_val_normalize(this); }
+ void normalize()
+ {
+ pj_time_val_normalize(this);
+ }
};