确保定时器能同步取消

This commit is contained in:
xiongziliang 2020-04-26 19:34:58 +08:00
parent 3651609a5f
commit 341bb5d84a

View File

@ -17,13 +17,13 @@ using namespace toolkit;
API_EXPORT mk_thread API_CALL mk_thread_from_tcp_session(mk_tcp_session ctx){ API_EXPORT mk_thread API_CALL mk_thread_from_tcp_session(mk_tcp_session ctx){
assert(ctx); assert(ctx);
TcpSession *obj = (TcpSession *)ctx; TcpSessionForC *obj = (TcpSessionForC *)ctx;
return obj->getPoller().get(); return obj->getPoller().get();
} }
API_EXPORT mk_thread API_CALL mk_thread_from_tcp_client(mk_tcp_client ctx){ API_EXPORT mk_thread API_CALL mk_thread_from_tcp_client(mk_tcp_client ctx){
assert(ctx); assert(ctx);
TcpClient::Ptr *client = (TcpClient::Ptr *)ctx; TcpClientForC::Ptr *client = (TcpClientForC::Ptr *)ctx;
return (*client)->getPoller().get(); return (*client)->getPoller().get();
} }
@ -43,18 +43,59 @@ API_EXPORT void API_CALL mk_sync_do(mk_thread ctx,on_mk_async cb, void *user_dat
}); });
} }
class TimerForC : public std::enable_shared_from_this<TimerForC>{
public:
typedef std::shared_ptr<TimerForC> Ptr;
TimerForC(on_mk_timer cb, void *user_data){
_cb = cb;
_user_data = user_data;
}
~TimerForC(){}
uint64_t operator()(){
lock_guard<recursive_mutex> lck(_mxt);
if(!_cb){
return 0;
}
return _cb(_user_data);
}
void cancel(){
lock_guard<recursive_mutex> lck(_mxt);
_cb = nullptr;
_task->cancel();
}
void start(int ms ,EventPoller &poller){
weak_ptr<TimerForC> weak_self = shared_from_this();
poller.doDelayTask(ms, [weak_self](){
auto strong_self = weak_self.lock();
if(!strong_self){
return (uint64_t)0;
}
return (*strong_self)();
});
}
private:
on_mk_timer _cb = nullptr;
void *_user_data = nullptr;
recursive_mutex _mxt;
DelayTask::Ptr _task;
};
API_EXPORT mk_timer API_CALL mk_timer_create(mk_thread ctx,uint64_t delay_ms,on_mk_timer cb, void *user_data){ API_EXPORT mk_timer API_CALL mk_timer_create(mk_thread ctx,uint64_t delay_ms,on_mk_timer cb, void *user_data){
assert(ctx && cb); assert(ctx && cb);
EventPoller *poller = (EventPoller *)ctx; EventPoller *poller = (EventPoller *)ctx;
auto ret = poller->doDelayTask(delay_ms,[cb,user_data](){ TimerForC::Ptr *ret = new TimerForC::Ptr(new TimerForC(cb, user_data));
return cb(user_data); (*ret)->start(delay_ms,*poller);
}); return ret;
return new DelayTask::Ptr(ret);
} }
API_EXPORT void API_CALL mk_timer_release(mk_timer ctx){ API_EXPORT void API_CALL mk_timer_release(mk_timer ctx){
assert(ctx); assert(ctx);
DelayTask::Ptr *obj = (DelayTask::Ptr *)ctx; TimerForC::Ptr *obj = (TimerForC::Ptr *)ctx;
(*obj)->cancel(); (*obj)->cancel();
delete obj; delete obj;
} }