2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "toolkit-event-thread-callback.h"
22 #include <semaphore.h>
33 // Note, this is not thread safe - however, should not be using
34 // triggers from multiple threads - they should all be created on
36 std::vector<Dali::EventThreadCallback*> gEventThreadCallbacks;
41 struct EventThreadCallback::Impl
43 CallbackBase* callback;
47 EventThreadCallback::EventThreadCallback(CallbackBase* callback)
50 mImpl->callback = callback;
51 sem_init(&(mImpl->mySemaphore), 0, 0);
53 gEventThreadCallbacks.push_back(this);
56 EventThreadCallback::~EventThreadCallback()
58 std::vector<EventThreadCallback*>::iterator iter =
59 std::find(gEventThreadCallbacks.begin(), gEventThreadCallbacks.end(), this);
60 if(iter != gEventThreadCallbacks.end())
62 gEventThreadCallbacks.erase(iter);
67 void EventThreadCallback::Trigger()
69 sem_post(&(mImpl->mySemaphore));
72 // returns true if timed out rather than triggered
73 bool EventThreadCallback::WaitingForTrigger()
76 clock_gettime(CLOCK_REALTIME, &now);
77 if(now.tv_nsec < 999900000) // 999, 900, 000
85 int error = sem_timedwait(&(mImpl->mySemaphore), &now);
86 return error != 0; // true if timeout
89 CallbackBase* EventThreadCallback::GetCallback()
91 return mImpl->callback;
98 bool WaitForEventThreadTrigger(int triggerCount, int timeoutInSeconds, int executeCallbacks)
100 struct timespec startTime;
102 clock_gettime(CLOCK_REALTIME, &startTime);
103 now.tv_sec = startTime.tv_sec;
104 now.tv_nsec = startTime.tv_nsec;
106 // Round robin poll of each semaphore:
107 while(triggerCount > 0)
109 if(gEventThreadCallbacks.size() > 0)
111 for(std::vector<Dali::EventThreadCallback*>::iterator iter = gEventThreadCallbacks.begin();
112 iter != gEventThreadCallbacks.end();
115 Dali::EventThreadCallback* eventTrigger = (*iter);
116 Dali::CallbackBase* callback = eventTrigger->GetCallback();
117 bool timedout = eventTrigger->WaitingForTrigger();
122 // Semaphore was unlocked - execute the trigger
123 Dali::CallbackBase::Execute(*callback);
127 if(triggerCount <= 0)
133 clock_gettime(CLOCK_REALTIME, &now);
134 if(now.tv_sec - startTime.tv_sec > timeoutInSeconds)
136 // Ensure we break out of the loop if elapsed time has passed
141 clock_gettime(CLOCK_REALTIME, &now);
142 if(now.tv_sec > startTime.tv_sec + 1)
144 fprintf(stderr, "WaitForEventThreadTrigger took %ld seconds\n", now.tv_sec - startTime.tv_sec);
146 return triggerCount == 0;