From 8f426164cc8b5ca4ea96766bf78fd2d1f28cd656 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Thu, 3 May 2007 13:31:21 +0000 Subject: Implemented ticket #246, #247, #261, #268, #250 for Symbian git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1246 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/src/pj/timer_symbian.cpp | 272 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 pjlib/src/pj/timer_symbian.cpp (limited to 'pjlib/src/pj/timer_symbian.cpp') diff --git a/pjlib/src/pj/timer_symbian.cpp b/pjlib/src/pj/timer_symbian.cpp new file mode 100644 index 00000000..398f7722 --- /dev/null +++ b/pjlib/src/pj/timer_symbian.cpp @@ -0,0 +1,272 @@ +/* $Id$ */ +/* + * Copyright (C)2003-2007 Benny Prijono + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include "os_symbian.h" + + +#define DEFAULT_MAX_TIMED_OUT_PER_POLL (64) + + +/** + * The implementation of timer heap. + */ +struct pj_timer_heap_t +{ + /** Maximum size of the heap. */ + pj_size_t max_size; + + /** Current size of the heap. */ + pj_size_t cur_size; + + /** Max timed out entries to process per poll. */ + unsigned max_entries_per_poll; +}; + + +////////////////////////////////////////////////////////////////////////////// +/** + * Active object for each timer entry. + */ +class CPjTimerEntry : public CActive +{ +public: + static CPjTimerEntry* NewL( pj_timer_heap_t *timer_heap, + pj_timer_entry *entry, + const pj_time_val *delay); + + ~CPjTimerEntry(); + + virtual void RunL(); + virtual void DoCancel(); + +private: + pj_timer_heap_t *timer_heap_; + pj_timer_entry *entry_; + RTimer rtimer_; + + CPjTimerEntry(pj_timer_heap_t *timer_heap, pj_timer_entry *entry); + void ConstructL(const pj_time_val *delay); +}; + + +CPjTimerEntry::CPjTimerEntry(pj_timer_heap_t *timer_heap, + pj_timer_entry *entry) +: CActive(PJ_SYMBIAN_TIMER_PRIORITY), timer_heap_(timer_heap), entry_(entry) +{ +} + +CPjTimerEntry::~CPjTimerEntry() +{ + if (IsActive()) + Cancel(); + rtimer_.Close(); +} + +void CPjTimerEntry::ConstructL(const pj_time_val *delay) +{ + rtimer_.CreateLocal(); + CActiveScheduler::Add(this); + + rtimer_.After(iStatus, PJ_TIME_VAL_MSEC(*delay) * 1000); + SetActive(); +} + +CPjTimerEntry* CPjTimerEntry::NewL(pj_timer_heap_t *timer_heap, + pj_timer_entry *entry, + const pj_time_val *delay) +{ + CPjTimerEntry *self = new CPjTimerEntry(timer_heap, entry); + CleanupStack::PushL(self); + self->ConstructL(delay); + CleanupStack::Pop(self); + + return self; +} + +void CPjTimerEntry::RunL() +{ + --timer_heap_->cur_size; + entry_->_timer_id = NULL; + entry_->cb(timer_heap_, entry_); + + // Finger's crossed! + delete this; +} + +void CPjTimerEntry::DoCancel() +{ + rtimer_.Cancel(); +} + + +////////////////////////////////////////////////////////////////////////////// + + +/* + * Calculate memory size required to create a timer heap. + */ +PJ_DEF(pj_size_t) pj_timer_heap_mem_size(pj_size_t count) +{ + return /* size of the timer heap itself: */ + sizeof(pj_timer_heap_t) + + /* size of each entry: */ + (count+2) * (sizeof(pj_timer_entry*)+sizeof(pj_timer_id_t)) + + /* lock, pool etc: */ + 132; +} + +/* + * Create a new timer heap. + */ +PJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool, + pj_size_t size, + pj_timer_heap_t **p_heap) +{ + pj_timer_heap_t *ht; + + PJ_ASSERT_RETURN(pool && p_heap, PJ_EINVAL); + + *p_heap = NULL; + + /* Allocate timer heap data structure from the pool */ + ht = PJ_POOL_ALLOC_T(pool, pj_timer_heap_t); + if (!ht) + return PJ_ENOMEM; + + /* Initialize timer heap sizes */ + ht->max_size = size; + ht->cur_size = 0; + ht->max_entries_per_poll = DEFAULT_MAX_TIMED_OUT_PER_POLL; + + *p_heap = ht; + return PJ_SUCCESS; +} + +PJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht ) +{ + PJ_UNUSED_ARG(ht); +} + +PJ_DEF(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht, + pj_lock_t *lock, + pj_bool_t auto_del ) +{ + PJ_UNUSED_ARG(ht); + if (auto_del) + pj_lock_destroy(lock); +} + + +PJ_DEF(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht, + unsigned count ) +{ + unsigned old_count = ht->max_entries_per_poll; + ht->max_entries_per_poll = count; + return old_count; +} + +PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry, + int id, + void *user_data, + pj_timer_heap_callback *cb ) +{ + pj_assert(entry && cb); + + entry->_timer_id = NULL; + entry->id = id; + entry->user_data = user_data; + entry->cb = cb; + + return entry; +} + +PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay) +{ + CPjTimerEntry *timerObj; + + PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL); + PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL); + + /* Prevent same entry from being scheduled more than once */ + PJ_ASSERT_RETURN(entry->_timer_id == NULL, PJ_EINVALIDOP); + + timerObj = CPjTimerEntry::NewL(ht, entry, delay); + entry->_timer_id = (void*) timerObj; + + ++ht->cur_size; + return PJ_SUCCESS; +} + +PJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht, + pj_timer_entry *entry) +{ + PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL); + + if (entry->_timer_id != NULL) { + CPjTimerEntry *timerObj = (CPjTimerEntry*) entry->_timer_id; + timerObj->Cancel(); + delete timerObj; + entry->_timer_id = NULL; + --ht->cur_size; + return 1; + } else { + return 0; + } +} + +PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, + pj_time_val *next_delay ) +{ + /* Polling is not necessary on Symbian, since all async activities + * are registered to active scheduler. + */ + PJ_UNUSED_ARG(ht); + if (next_delay) { + next_delay->sec = 1; + next_delay->msec = 0; + } + return 0; +} + +PJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht ) +{ + PJ_ASSERT_RETURN(ht, 0); + + return ht->cur_size; +} + +PJ_DEF(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t * ht, + pj_time_val *timeval) +{ + /* We don't support this! */ + PJ_UNUSED_ARG(ht); + + timeval->sec = 1; + timeval->msec = 0; + + return PJ_SUCCESS; +} + -- cgit v1.2.3