void Task::Signal(EventFlags events)
{
if (!this->Valid())
return;
//Fancy no mutex implementation. We atomically mask the new events into
//the event mask. Because atomic_or returns the old state of the mask,
//we only schedule this task once.
events |= kAlive;
EventFlags oldEvents = atomic_or(&fEvents, events);
if ((!(oldEvents & kAlive)) && (TaskThreadPool::sNumTaskThreads > 0))
{
if (fDefaultThread != NULL && fUseThisThread == NULL)
fUseThisThread = fDefaultThread;
if (fUseThisThread != NULL)
{
// Task needs to be placed on a particular thread.
if (TASK_DEBUG)
{
if (fTaskName[0] == 0) ::strcpy(fTaskName, " corrupt task");
qtss_printf("Task::Signal enque TaskName=%s fUseThisThread=%p q elem=%p enclosing=%p\n", fTaskName, (void *) fUseThisThread, (void *) &fTaskQueueElem, (void *) this);
if (TaskThreadPool::sTaskThreadArray[0] == fUseThisThread) qtss_printf("Task::Signal RTSP Thread running TaskName=%s \n", fTaskName);
}
// The particular thread gotten, enqueue task to the thread
fUseThisThread->fTaskQueue.EnQueue(&fTaskQueueElem);
}
else
{
//find a thread to put this task on
unsigned int theThreadIndex = atomic_add( (unsigned int *) pickerToUse, 1);
if (&Task::sShortTaskThreadPicker == pickerToUse)
{
theThreadIndex %= TaskThreadPool::sNumShortTaskThreads;
if (TASK_DEBUG) qtss_printf("Task::Signal enque TaskName=%s using Task::sShortTaskThreadPicker=%u numShortTaskThreads=%"_U32BITARG_" short task range=[0-%"_U32BITARG_"] thread index =%u \n",fTaskName, Task::sShortTaskThreadPicker, TaskThreadPool::sNumShortTaskThreads,TaskThreadPool::sNumShortTaskThreads -1, theThreadIndex);
}
else if (&Task::sBlockingTaskThreadPicker == pickerToUse)
{
theThreadIndex %= TaskThreadPool::sNumBlockingTaskThreads;
theThreadIndex += TaskThreadPool::sNumShortTaskThreads; //don't pick from lower non-blocking (short task) threads.
if (TASK_DEBUG) qtss_printf("Task::Signal enque TaskName=%s using Task::sBlockingTaskThreadPicker=%u numBlockingThreads=%"_U32BITARG_" blocking thread range=[%"_U32BITARG_"-%"_U32BITARG_"] thread index =%u \n",fTaskName, Task::sBlockingTaskThreadPicker, TaskThreadPool::sNumBlockingTaskThreads, TaskThreadPool::sNumShortTaskThreads, TaskThreadPool::sNumBlockingTaskThreads+TaskThreadPool::sNumShortTaskThreads-1, theThreadIndex);
}
else
{
if (TASK_DEBUG) if (fTaskName[0] == 0) ::strcpy(fTaskName, " corrupt task");
return;
}
if (TASK_DEBUG) if (fTaskName[0] == 0) ::strcpy(fTaskName, " corrupt task");
if (TASK_DEBUG) qtss_printf("Task::Signal enque TaskName=%s theThreadIndex=%u thread=%p q elem=%p enclosing=%p\n", fTaskName,theThreadIndex, (void *)TaskThreadPool::sTaskThreadArray[theThreadIndex],(void *) &fTaskQueueElem,(void *) this);
// A task thread gotten, and enqueue task to the thread.
TaskThreadPool::sTaskThreadArray[theThreadIndex]->fTaskQueue.EnQueue(&fTaskQueueElem);
}
}
else
if (TASK_DEBUG) qtss_printf("Task::Signal sent to dead TaskName=%s q elem=%p enclosing=%p\n", fTaskName, (void *) &fTaskQueueElem, (void *) this);
}
{
if (!this->Valid())
return;
//Fancy no mutex implementation. We atomically mask the new events into
//the event mask. Because atomic_or returns the old state of the mask,
//we only schedule this task once.
events |= kAlive;
EventFlags oldEvents = atomic_or(&fEvents, events);
if ((!(oldEvents & kAlive)) && (TaskThreadPool::sNumTaskThreads > 0))
{
if (fDefaultThread != NULL && fUseThisThread == NULL)
fUseThisThread = fDefaultThread;
if (fUseThisThread != NULL)
{
// Task needs to be placed on a particular thread.
if (TASK_DEBUG)
{
if (fTaskName[0] == 0) ::strcpy(fTaskName, " corrupt task");
qtss_printf("Task::Signal enque TaskName=%s fUseThisThread=%p q elem=%p enclosing=%p\n", fTaskName, (void *) fUseThisThread, (void *) &fTaskQueueElem, (void *) this);
if (TaskThreadPool::sTaskThreadArray[0] == fUseThisThread) qtss_printf("Task::Signal RTSP Thread running TaskName=%s \n", fTaskName);
}
// The particular thread gotten, enqueue task to the thread
fUseThisThread->fTaskQueue.EnQueue(&fTaskQueueElem);
}
else
{
//find a thread to put this task on
unsigned int theThreadIndex = atomic_add( (unsigned int *) pickerToUse, 1);
if (&Task::sShortTaskThreadPicker == pickerToUse)
{
theThreadIndex %= TaskThreadPool::sNumShortTaskThreads;
if (TASK_DEBUG) qtss_printf("Task::Signal enque TaskName=%s using Task::sShortTaskThreadPicker=%u numShortTaskThreads=%"_U32BITARG_" short task range=[0-%"_U32BITARG_"] thread index =%u \n",fTaskName, Task::sShortTaskThreadPicker, TaskThreadPool::sNumShortTaskThreads,TaskThreadPool::sNumShortTaskThreads -1, theThreadIndex);
}
else if (&Task::sBlockingTaskThreadPicker == pickerToUse)
{
theThreadIndex %= TaskThreadPool::sNumBlockingTaskThreads;
theThreadIndex += TaskThreadPool::sNumShortTaskThreads; //don't pick from lower non-blocking (short task) threads.
if (TASK_DEBUG) qtss_printf("Task::Signal enque TaskName=%s using Task::sBlockingTaskThreadPicker=%u numBlockingThreads=%"_U32BITARG_" blocking thread range=[%"_U32BITARG_"-%"_U32BITARG_"] thread index =%u \n",fTaskName, Task::sBlockingTaskThreadPicker, TaskThreadPool::sNumBlockingTaskThreads, TaskThreadPool::sNumShortTaskThreads, TaskThreadPool::sNumBlockingTaskThreads+TaskThreadPool::sNumShortTaskThreads-1, theThreadIndex);
}
else
{
if (TASK_DEBUG) if (fTaskName[0] == 0) ::strcpy(fTaskName, " corrupt task");
return;
}
if (TASK_DEBUG) if (fTaskName[0] == 0) ::strcpy(fTaskName, " corrupt task");
if (TASK_DEBUG) qtss_printf("Task::Signal enque TaskName=%s theThreadIndex=%u thread=%p q elem=%p enclosing=%p\n", fTaskName,theThreadIndex, (void *)TaskThreadPool::sTaskThreadArray[theThreadIndex],(void *) &fTaskQueueElem,(void *) this);
// A task thread gotten, and enqueue task to the thread.
TaskThreadPool::sTaskThreadArray[theThreadIndex]->fTaskQueue.EnQueue(&fTaskQueueElem);
}
}
else
if (TASK_DEBUG) qtss_printf("Task::Signal sent to dead TaskName=%s q elem=%p enclosing=%p\n", fTaskName, (void *) &fTaskQueueElem, (void *) this);
}