#include #include "aeTask.h" #include "arplayer.h" TaskItem::TaskItem(string theName, void (*theProc)(TaskItem *), void *uDataPtr, unsigned long theUID, unsigned long theLifeTime, unsigned char allowDelete) { finished = false; name = theName; userData = uDataPtr; Proc = theProc; UID = theUID; if(UID) registerMetaUser(UID); delUID = allowDelete; timeOut = theLifeTime; pthread_create(&thread, NULL, &TaskItem::CallProcInThread, this); pthread_detach(thread); } TaskItem::~TaskItem(void) { if(thread) pthread_cancel(thread); // remove from task list tMutex->readLock(true); vector::iterator lp = TaskList.begin(); for(unsigned int x=0; xwriteLock(true); TaskList.erase(lp); tMutex->writeUnlock(); } lp++; } tMutex->readUnlock(); if(delUID){ // if there is a corrisponding playlist item (with UID), delete it too. unsigned int passUID = UID; lMutex->readLock(true); if(getListPos(&passUID)){ DeleteItem(passUID); } lMutex->readUnlock(); } deleteMetaRecord(UID); } void TaskItem::AddSelf(void) { tMutex->writeLock(true); vector::iterator lp = TaskList.begin(); TaskList.insert(lp, this); tMutex->writeUnlock(); } void *TaskItem::CallProcInThread(void *inRefCon) { TaskItem *taskInstance = (TaskItem *)inRefCon; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); registerMetaUser(taskInstance->UID); taskInstance->AddSelf(); (*taskInstance->Proc)(taskInstance); taskInstance->finished = true; pthread_exit(0); } //********************** Tasks routines here ************************// void UnlockAdvancedReadLock(Lock *theLock) { // c++ to c conversion theLock->readUnlock(); } void RefreshMutesGroups(TaskItem *parent) { unsigned long newMute; ARPlayer *instance; int i; // get current mute groupe state newMute = 0L; pthread_cleanup_push((void (*)(void *))UnlockAdvancedReadLock, (void *)pMutex); pMutex->readLock(true); for(i = 0; i < inBusNum; i++){ if(pList[i] != NULL){ instance = pList[i]; if (instance->status & status_playing){ pthread_testcancel(); // this player is playing! Note the buses used. newMute = newMute | instance->bus_assignment; } } } pthread_cleanup_pop(1); // run through the output distributor list updateing the muste group state pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, (void *) &oMutex); pthread_mutex_lock(&oMutex); output_map_ptr dp; for (dp=outputMap.begin(); dp!=outputMap.end(); dp++){ pthread_testcancel(); (*dp).second.SetMute(newMute); } pthread_cleanup_pop(1); } void ExecuteCommand(TaskItem *parent) { unsigned long lastUID; char *command; command = (char*)(parent->userData); processCommand(0, command, &lastUID, true); free(command); } void WaitPID(TaskItem *parent) { struct execRec{ char **argv; char *str; pid_t child; } *recPtr; recPtr = (struct execRec*)parent->userData; // wait for child process to complete waitpid(recPtr->child, NULL, 0); // all done - clean up and return free(recPtr->argv); free(recPtr->str); free(recPtr); }