blob: 09627b5a0efdfbc6237bff0761c64ea2e756b378
1 | #include "CMsgQueue.h" |
2 | #include <CTvLog.h> |
3 | #include <utils/Timers.h> |
4 | CMessage::CMessage() |
5 | { |
6 | mDelayMs = 0; |
7 | mWhenMs = 0; |
8 | } |
9 | |
10 | CMessage::~CMessage() |
11 | { |
12 | |
13 | } |
14 | |
15 | CMsgQueueThread::CMsgQueueThread() |
16 | { |
17 | |
18 | } |
19 | |
20 | CMsgQueueThread::~CMsgQueueThread() |
21 | { |
22 | //请求退出处理线程,并阻塞 |
23 | requestExitAndWait(); |
24 | } |
25 | |
26 | nsecs_t CMsgQueueThread::getNowMs() |
27 | { |
28 | return systemTime(SYSTEM_TIME_MONOTONIC) / 1000000; |
29 | } |
30 | void CMsgQueueThread::sendMsg(CMessage &msg) |
31 | { |
32 | CMutex::Autolock _l(mLockQueue); |
33 | msg.mWhenMs = getNowMs() + msg.mDelayMs;// |
34 | |
35 | int i = 0; |
36 | while(i < m_v_msg.size() && m_v_msg[i].mWhenMs <= msg.mWhenMs) i++;//find the index that will insert(i) |
37 | m_v_msg.insertAt(msg, i);//insert at index i |
38 | CMessage msg1 = m_v_msg[0]; |
39 | LOGD("sendmsg now2 = %lld i = %d", getNowMs(), i); |
40 | LOGD("sendmsg now3 = %lld msg1 when = %lld", getNowMs(), msg1.mWhenMs); |
41 | // |
42 | //if(i == 0)// is empty or new whenMS is at index 0, low all ms in list. so ,need to wakeup loop, to get new delay time. |
43 | mGetMsgCondition.signal(); |
44 | } |
45 | //有个缺陷,只能根据消息类型移除,同类型消息会全部移除,但足够用了 |
46 | void CMsgQueueThread::removeMsg(CMessage &msg) |
47 | { |
48 | CMutex::Autolock _l(mLockQueue); |
49 | int beforeSize = m_v_msg.size(); |
50 | for (int i = 0; i < m_v_msg.size(); i++) { |
51 | const CMessage &_msg = m_v_msg.itemAt(i); |
52 | if (_msg.mType == msg.mType) { |
53 | m_v_msg.removeAt(i); |
54 | } |
55 | } |
56 | //some msg removeed |
57 | if(beforeSize > m_v_msg.size()) |
58 | mGetMsgCondition.signal(); |
59 | } |
60 | |
61 | int CMsgQueueThread::startMsgQueue() |
62 | { |
63 | CMutex::Autolock _l(mLockQueue); |
64 | this->run(); |
65 | return 0; |
66 | } |
67 | |
68 | bool CMsgQueueThread::threadLoop() |
69 | { |
70 | int sleeptime = 100;//ms |
71 | |
72 | while(!exitPending()) { //requietexit() or requietexitWait() not call |
73 | mLockQueue.lock(); |
74 | while(m_v_msg.size() == 0) { //msg queue is empty |
75 | mGetMsgCondition.wait(mLockQueue);//first unlock,when return,lock again,so need,call unlock |
76 | } |
77 | mLockQueue.unlock(); |
78 | //get delay time |
79 | CMessage msg; |
80 | nsecs_t delayMs = 0, nowMS = 0; |
81 | do { //wait ,until , the lowest time msg's whentime is low nowtime, to go on |
82 | if(m_v_msg.size() <= 0) { |
83 | LOGD("msg size is 0, break"); |
84 | break; |
85 | } |
86 | mLockQueue.lock();//get msg ,first lock. |
87 | msg = m_v_msg[0];//get first |
88 | mLockQueue.unlock(); |
89 | |
90 | delayMs = msg.mWhenMs - getNowMs(); |
91 | LOGD("threadLoop now = %lld mswhen = %lld delayMs = %lld msg type = %d", getNowMs(), msg.mWhenMs, delayMs, msg.mType); |
92 | if(delayMs > 0) { |
93 | mLockQueue.lock();//get msg ,first lock. |
94 | int ret = mGetMsgCondition.waitRelative(mLockQueue, delayMs); |
95 | mLockQueue.unlock(); |
96 | LOGD("msg queue wait ret = %d", ret); |
97 | } else { |
98 | break; |
99 | } |
100 | } while(true); //msg[0], timeout |
101 | |
102 | if(m_v_msg.size() > 0) { |
103 | mLockQueue.lock();// |
104 | msg = m_v_msg[0]; |
105 | m_v_msg.removeAt(0); |
106 | mLockQueue.unlock();// |
107 | //handle it |
108 | handleMessage(msg); |
109 | } |
110 | |
111 | //usleep(sleeptime * 1000); |
112 | } |
113 | //exit |
114 | //return true, run again, return false,not run. |
115 | return false; |
116 | } |
117 |