26 #include <sys/fcntl.h>
27 #include <sys/errno.h>
47 mLastInsertedHandle(0),
48 mLastInsertedPollHandle(0),
49 mRecreatePollfds(true),
52 if (pipe(mPipe) == -1)
54 logError(
"Sockethandler could not create pipe!");
81 sigemptyset(&sigmask);
82 sigaddset(&sigmask, SIGINT);
83 sigaddset(&sigmask, SIGQUIT);
84 sigaddset(&sigmask, SIGTERM);
85 sigaddset(&sigmask, SIGHUP);
86 sigaddset(&sigmask, SIGQUIT);
88 clock_gettime(CLOCK_MONOTONIC, &mStartTime);
89 while (!mDispatchDone)
92 std::for_each(mListPoll.begin(), mListPoll.end(), CAmShCallPrep());
96 mfdPollingArray.clear();
98 std::for_each(mListPoll.begin(), mListPoll.end(), CAmShCopyPollfd(mfdPollingArray));
99 mRecreatePollfds =
false;
107 if ((pollStatus = ppoll(&mfdPollingArray[0], mfdPollingArray.size(), insertTime(buffertime), &sigmask)) < 0)
116 logError(
"SocketHandler::start_listenting ppoll returned with error", errno);
117 throw std::runtime_error(std::string(
"SocketHandler::start_listenting ppoll returned with error."));
126 std::list<sh_poll_s> listPoll;
127 mListPoll_t::iterator listmPollIt;
130 std::vector<pollfd>::iterator it = mfdPollingArray.begin();
133 it = std::find_if(it, mfdPollingArray.end(), eventFired);
134 if (it != mfdPollingArray.end())
136 listmPollIt = mListPoll.begin();
137 std::advance(listmPollIt, std::distance(mfdPollingArray.begin(), it));
138 listPoll.push_back(*listmPollIt);
139 listPoll.back().pollfdValue = *it;
142 }
while (it != mfdPollingArray.end());
145 std::for_each(listPoll.begin(), listPoll.end(), CAmShCallFire());
148 listPoll.remove_if(noDispatching);
153 listPoll.remove_if(dispatchingFinished);
154 }
while (!listPoll.empty());
173 if (!mListActiveTimer.empty())
175 timespec currentTime, correctionTime;
176 clock_gettime(CLOCK_MONOTONIC, ¤tTime);
177 correctionTime = timespecSub(currentTime, mStartTime);
178 std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime));
204 ++mLastInsertedPollHandle;
207 mLastInsertedPollHandle = 1;
209 if (mLastInsertedPollHandle==lastHandle)
211 logError(__func__,
"Could not create new polls, too many open!");
215 }
while (mSetPollKeys.find(mLastInsertedPollHandle) != mSetPollKeys.end());
217 mSetPollKeys.insert(mLastInsertedPollHandle);
220 pollData.pollfdValue.fd = fd;
221 pollData.handle = mLastInsertedPollHandle;
222 pollData.pollfdValue.events = event;
223 pollData.pollfdValue.revents = 0;
224 pollData.userData = userData;
225 pollData.prepareCB = prepare;
226 pollData.firedCB = fired;
227 pollData.checkCB = check;
228 pollData.dispatchCB = dispatch;
231 mListPoll.push_back(pollData);
233 mRecreatePollfds =
true;
235 handle = pollData.handle;
246 mListPoll_t::iterator iterator = mListPoll.begin();
248 for (; iterator != mListPoll.end(); ++iterator)
250 if (iterator->handle == handle)
252 iterator = mListPoll.erase(iterator);
253 mSetPollKeys.erase(handle);
254 mRecreatePollfds =
true;
274 assert(!((timeouts.tv_sec==0) && (timeouts.tv_nsec==0)));
275 assert(callback!=NULL);
277 sh_timer_s timerItem;
283 ++mLastInsertedHandle;
286 mLastInsertedHandle = 1;
288 if (lastTimerHandle==mLastInsertedHandle)
290 logError(__func__,
"Could not create new timers, too many open!");
294 }
while (mSetTimerKeys.find(mLastInsertedHandle) != mSetTimerKeys.end());
296 mSetTimerKeys.insert(mLastInsertedHandle);
297 handle=mLastInsertedHandle;
298 timerItem.handle = handle;
299 timerItem.countdown = timeouts;
300 timerItem.callback = callback;
301 timerItem.userData = userData;
303 mListTimer.push_back(timerItem);
306 timespec currentTime;
307 clock_gettime(CLOCK_MONOTONIC, ¤tTime);
309 timerItem.countdown = timespecAdd(timeouts, timespecSub(currentTime, mStartTime));
311 mListActiveTimer.push_back(timerItem);
312 mListActiveTimer.sort(compareCountdown);
328 std::list<sh_timer_s>::iterator it(mListTimer.begin());
329 for (; it != mListTimer.end(); ++it)
331 if (it->handle == handle)
333 it = mListTimer.erase(it);
334 mSetTimerKeys.erase(handle);
350 sh_timer_s timerItem;
351 std::list<sh_timer_s>::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin());
353 for (; it != mListTimer.end(); ++it)
355 if (it->handle == handle)
357 it->countdown = timeouts;
369 timespec currentTime, timeoutsCorrected;
370 currentTime.tv_nsec=timeoutsCorrected.tv_nsec=0;
371 currentTime.tv_sec=timeoutsCorrected.tv_sec=0;
372 clock_gettime(CLOCK_MONOTONIC, ¤tTime);
374 timeoutsCorrected = timespecAdd(timeouts, timespecSub(currentTime, mStartTime));
376 for (; activeIt != mListActiveTimer.end(); ++activeIt)
378 if (activeIt->handle == handle)
380 activeIt->countdown = timeoutsCorrected;
387 timerItem.countdown = timeoutsCorrected;
388 mListActiveTimer.push_back(timerItem);
390 mListActiveTimer.sort(compareCountdown);
401 sh_timer_s timerItem;
403 std::list<sh_timer_s>::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin());
405 for (; it != mListTimer.end(); ++it)
407 if (it->handle == handle)
420 timespec currentTime, timeoutsCorrected;
421 clock_gettime(CLOCK_MONOTONIC, ¤tTime);
424 timeoutsCorrected = timespecAdd(timerItem.countdown, timespecSub(currentTime, mStartTime));
425 timerItem.countdown = timeoutsCorrected;
428 for (; activeIt != mListActiveTimer.end(); ++activeIt)
430 if (activeIt->handle == handle)
432 activeIt->countdown = timerItem.countdown;
439 mListActiveTimer.push_back(timerItem);
441 mListActiveTimer.sort(compareCountdown);
454 std::list<sh_timer_s>::iterator it(mListActiveTimer.begin());
455 for (; it != mListActiveTimer.end(); ++it)
457 if (it->handle == handle)
459 it = mListActiveTimer.erase(it);
474 mListPoll_t::iterator iterator = mListPoll.begin();
476 for (; iterator != mListPoll.end(); ++iterator)
478 if (iterator->handle == handle)
480 iterator->pollfdValue.events = events;
481 mRecreatePollfds =
true;
493 bool CAmSocketHandler::fdIsValid(
const int fd)
const
495 return (fcntl(fd, F_GETFL) != -1 || errno != EBADF);
501 void CAmSocketHandler::timerUp()
504 timespec currentTime, diffTime;
505 clock_gettime(CLOCK_MONOTONIC, ¤tTime);
506 diffTime = timespecSub(currentTime, mStartTime);
509 std::list<sh_timer_s>::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownUp(diffTime));
512 std::vector<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
515 std::list<sh_timer_s>::iterator it(overflowIter.base());
516 mListActiveTimer.erase(mListActiveTimer.begin(), it);
519 std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer());
525 void CAmSocketHandler::timerCorrection()
528 timespec currentTime, correctionTime;
529 clock_gettime(CLOCK_MONOTONIC, ¤tTime);
530 correctionTime = timespecSub(currentTime, mStartTime);
531 mStartTime = currentTime;
533 if (!mListActiveTimer.empty())
537 std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime));
540 std::list<sh_timer_s>::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownZero());
543 if (overflowIter != mListActiveTimer.rend())
546 std::vector<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
549 std::list<sh_timer_s>::iterator it(overflowIter.base());
550 mListActiveTimer.erase(mListActiveTimer.begin(), it);
553 std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer());
565 ssize_t result = write(mPipe[1], &p,
sizeof(p));
573 inline timespec* CAmSocketHandler::insertTime(timespec& buffertime)
575 if (!mListActiveTimer.empty())
577 buffertime = mListActiveTimer.front().countdown;
578 return (&buffertime);
586 void CAmSocketHandler::CAmShCallFire::operator()(sh_poll_s& row)
590 row.firedCB->Call(row.pollfdValue, row.handle, row.userData);
592 catch (std::exception& e)
594 logError(
"Sockethandler: Exception in FireCallback,caught",e.what());
598 void CAmSocketHandler::CAmShCallPrep::operator()(sh_poll_s& row)
604 row.prepareCB->Call(row.handle, row.userData);
606 catch (std::exception& e)
608 logError(
"Sockethandler: Exception in Preparecallback,caught",e.what());
613 void CAmSocketHandler::CAmShCallTimer::operator()(sh_timer_s& row)
617 row.callback->Call(row.handle, row.userData);
619 catch (std::exception& e)
621 logError(
"Sockethandler: Exception in Timercallback,caught",e.what());
625 void CAmSocketHandler::CAmShCopyPollfd::operator()(
const sh_poll_s& row)
627 pollfd temp = row.pollfdValue;
629 mArray.push_back(temp);
632 bool CAmSocketHandler::CAmShCountdownUp::operator()(
const sh_timer_s& row)
634 timespec sub = timespecSub(row.countdown, mDiffTime);
635 if (sub.tv_nsec == 0 && sub.tv_sec == 0)
640 bool CAmSocketHandler::CAmShCountdownZero::operator()(
const sh_timer_s& row)
642 if (row.countdown.tv_nsec == 0 && row.countdown.tv_sec == 0)
the desired object is non existent
am_Error_e
the errors of the audiomanager.
prototype for poll fired callback
am_Error_e restartTimer(const sh_timerHandle_t handle)
restarts a timer with the original value
The am::CAmSocketHandler implements a mainloop for the AudioManager.
uint16_t sh_pollHandle_t
this is a handle for a filedescriptor to be used with the SocketHandler
am_Error_e addTimer(const timespec timeouts, IAmShTimerCallBack *callback, sh_timerHandle_t &handle, void *userData)
adds a timer to the list of timers.
SPDX license identifier: MPL-2.0.
TAmShPollFired< CAmSocketHandler > receiverCallbackT
prototype for poll check callback
am_Error_e removeFDPoll(const sh_pollHandle_t handle)
removes a filedescriptor from the poll loop
prototype for poll prepared callback
uint16_t sh_timerHandle_t
this is a handle for a timer to be used with the SocketHandler
am_Error_e removeTimer(const sh_timerHandle_t handle)
removes a timer from the list of timers
am_Error_e stopTimer(const sh_timerHandle_t handle)
stops a timer
am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void *userData, sh_pollHandle_t &handle)
Adds a filedescriptor to the polling loop.
am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events)
updates the eventFlags of a poll
void start_listenting()
start the block listening for filedescriptors.
prototype for dispatch callback
TAmShPollCheck< CAmSocketHandler > checkerCallbackT
the desired action is not possible
am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec timeouts)
restarts a timer and updates with a new interva
SPDX license identifier: MPL-2.0.
void logError(T value, TArgs...args)
logs given values with errorlevel with the default context
prototype for the timer callback
no error - positive reply
void stop_listening()
exits the loop