123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- #include "stdafx.h"
- #include "SpBase.h"
- #include "SpEntity.h"
- #include "SpModule.h"
- #include "SpTimer.h"
- #include "SpMisc.h"
- #include "gettimeofday.h"
- #include "list.h"
- #include "spinlock.h"
- #include "memutil.h"
- #include "refcnt.h"
- //#include "hash.h"
- //#include "hashset.h"
- //#include "jhash.h"
- #include "sp_svc.h"
- #include "sp_dbg_export.h"
- #include "sp_tmr.h"
- #ifdef _WIN32
- #include "sp_checkEntity.h"
- #endif //_WIN32
- struct SpTimer_key_t
- {
- DWORD dwTimerID;
- };
- struct SpTimer
- {
- struct hlist_node hentry;
- DWORD dwInterval;
- SpTimer_key_t key;
- SpEntity *pEntity;
- volatile LONG lStop;
- IReleasable *pUserData;
- ITimerListener *pListener;
- struct timeval tmNext;
- sp_tmr_t *tmr;
- SpTimerList *pList;
- spinlock_t lock;
- DECLARE_REF_COUNT_MEMBER(iRefCount);
- };
- struct SpTimerList
- {
- SpEntity *pEntity;
- spinlock_t lock;
- htable_t *ht_timer;
- };
- static __inline unsigned int timer_key_hasher(const SpTimer_key_t *key)
- {
- return key->dwTimerID;
- }
- static __inline int timer_key_cmp(const SpTimer_key_t *key1, const SpTimer_key_t *key2)
- {
- return (int)key1->dwTimerID - (int)key2->dwTimerID;
- }
- IMPLEMENT_HTABLE_STATIC(timer, SpTimer_key_t, SpTimer, key, hentry, timer_key_hasher, timer_key_cmp)
- static void __SpTimerDestroy(SpTimer *pTimer)
- {
- //sp_dbg_info("SpTimer Destroy dwTimerId=%d",pTimer->key.dwTimerID);
- sp_tmr_destroy(pTimer->tmr);
- if (pTimer->pUserData) {
- delete pTimer->pUserData;
- pTimer->pUserData = NULL;
- }
- pTimer->tmr = NULL;
- }
- IMPLEMENT_REF_COUNT_MT_STATIC(SpTimer, SpTimer, iRefCount, __SpTimerDestroy)
- static void tmr_callback(sp_tmr_t *timer, int err, void *user_data)
- {
- SpTimer *pTimer = (SpTimer *)user_data;
- if (!err && !pTimer->lStop) {
- //Dbg("tmr_callback setEntity:%x", pTimer->pList->pEntity);
- #ifdef _WIN32
- getEntityResource()->m_Entity = pTimer->pList->pEntity;
- #else
- GetSpModule()->SetThreadEntity(pTimer->pList->pEntity);
- #endif //_WIN32
- pTimer->pListener->OnTimeout(pTimer->key.dwTimerID); // OnTimeout()
- spinlock_enter(&pTimer->lock, -1);
- if (!pTimer->lStop) { /* user may cancel in callback function */
- unsigned int delay;
- struct timeval now;
-
- gettimeofday(&pTimer->tmNext, NULL); // 以当前时间重置定时器,防止修改系统时间造成死循环
- timeval_add_msec(&pTimer->tmNext, pTimer->dwInterval);
-
- /*gettimeofday(&now, NULL);
- if (timeval_cmp(&now, &pTimer->tmNext) >= 0) {
- delay = 0;
- } else {
- delay = timeval_sub(&pTimer->tmNext, &now);
- }*/
- delay = pTimer->dwInterval;
- SpTimer_inc_ref(pTimer);
- int rc = sp_tmr_schedule(timer, delay);
- if (rc != 0) {
- SpTimer_dec_ref(pTimer);
- sp_dbg_debug("internal schedule timer failed!");
- }
- }
- spinlock_leave(&pTimer->lock);
- }
- SpTimer_dec_ref(pTimer);
- }
- SpTimer *SpTimerCreate(SpTimerList *pList, DWORD dwTimerID, DWORD dwInterval, ITimerListener *pListener)
- {
- sp_svc_t *svc;
- SpTimer *pTimer = MALLOC_T(SpTimer);
- int rc;
- sp_tmr_callback cb;
- svc = (sp_svc_t*)pList->pEntity->get_svc();
- INIT_HLIST_NODE(&pTimer->hentry);
- pTimer->pList = pList;
- pTimer->pEntity = pList->pEntity;
- pTimer->dwInterval = dwInterval;
- pTimer->key.dwTimerID = dwTimerID;
- pTimer->pListener = pListener;
- pTimer->pUserData = NULL;
- cb.user_data = pTimer;
- cb.on_timer = &tmr_callback;
- cb.on_destroy = NULL;
- rc = sp_tmr_create(sp_svc_get_tmr_mgr(svc), NULL, &cb, &pTimer->tmr);
- if (rc != 0) {
- sp_dbg_debug("create internal tmr failed!");
- free(pTimer);
- return NULL;
- }
- spinlock_init(&pTimer->lock);
- REF_COUNT_INIT(&pTimer->iRefCount);
- sp_dbg_info("SpTimer created dwTimerId = %d, dwInterval=%d", dwTimerID, dwInterval);
- return pTimer;
- }
- void SpTimerDestroy(SpTimer *pTimer)
- {
- SpTimer_dec_ref(pTimer);
- }
- void SpTimerSetUserData(SpTimer *pTimer, IReleasable *pUserData)
- {
- pTimer->pUserData = pUserData;
- }
- void SpTimerGetUserData(SpTimer *pTimer, CSmartPointer<IReleasable> &pUserData)
- {
- pUserData.Attach(pTimer->pUserData);
- pTimer->pUserData = NULL;
- }
- ErrorCodeEnum SpTimerStart(SpTimer *pTimer)
- {
- int rc;
- pTimer->lStop = 0;
- sp_svc_t* svc = static_cast<sp_svc_t*>(pTimer->pList->pEntity->get_svc());
- gettimeofday(&pTimer->tmNext, NULL);
- timeval_add_msec(&pTimer->tmNext, pTimer->dwInterval);
- SpTimer_inc_ref(pTimer);
- #ifdef _WIN32
- getEntityResource()->m_timer = pTimer;
- #endif //_WIN32
- rc = sp_tmr_schedule(pTimer->tmr, pTimer->dwInterval);
- if (rc != 0) {
- SpTimer_dec_ref(pTimer);
- sp_tmr_destroy(pTimer->tmr);
- pTimer->tmr = NULL;
- return SpTranslateError(rc);
- }
- return Error_Succeed;
- }
- void SpTimerStop(SpTimer *pTimer)
- {
- if (pTimer->lStop)
- return;
- InterlockedExchange(&pTimer->lStop, 1);
- spinlock_enter(&pTimer->lock, -1);
- sp_tmr_cancel(pTimer->tmr);
- spinlock_leave(&pTimer->lock);
- }
- void SpTimerSetInterval(SpTimer *pTimer, DWORD dwInterval)
- {
- pTimer->dwInterval = dwInterval;
- }
- DWORD SpTimerGetInterval(SpTimer *pTimer)
- {
- return pTimer->dwInterval;
- }
- SpTimerList *SpTimerListCreate(SpEntity *pEntity)
- {
- SpTimerList *pList = MALLOC_T(SpTimerList);
- spinlock_init(&pList->lock);
- pList->ht_timer = htable_create(0);
- pList->pEntity = pEntity;
- return pList;
- }
- void SpTimerListDestroy(SpTimerList *pList)
- {
- assert(pList);
- assert(pList->ht_timer->count == 0);
- htable_destroy(pList->ht_timer);
- free(pList);
- }
- SpTimer *SpTimerListFind(SpTimerList *pList, DWORD dwTimerID)
- {
- assert(pList);
- SpTimer_key_t key = {dwTimerID};
- SpTimer* pTimer = timer_find(pList->ht_timer, &key);
- return pTimer;
- }
- void SpTimerListAdd(SpTimerList *pList, SpTimer *pTimer)
- {
- assert(pTimer);
- timer_add(pList->ht_timer, pTimer);
- }
- void SpTimerListRemove(SpTimerList *pList, SpTimer *pTimer)
- {
- assert(pTimer);
- timer_remove(pList->ht_timer, pTimer);
- }
- void SpTimerListLock(SpTimerList *pList)
- {
- assert(pList);
- spinlock_enter(&pList->lock, -1);
- }
- void SpTimerListUnlock(SpTimerList *pList)
- {
- assert(pList);
- spinlock_leave(&pList->lock);
- }
- void SpTimerListStopAll(SpTimerList *pList)
- {
- for (int i = 0; i < pList->ht_timer->size; ++i) {
- SpTimer *tpos;
- struct hlist_node *pos;
- hlist_for_each_entry(tpos, pos, &pList->ht_timer->buckets[i], SpTimer, hentry) {
- SpTimerStop(tpos);
- }
- }
- }
|