You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/mpeglib/lib/decoder/commandPipe.cpp

164 lines
3.0 KiB

/*
thread safe fifo queue for commands
Copyright (C) 2000 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file COPYRIGHT in this package
*/
#include "commandPipe.h"
#define _COMMAND_ARRAY_SIZE 100
CommandPipe::CommandPipe() {
abs_thread_cond_init(&spaceCond);
abs_thread_cond_init(&emptyCond);
abs_thread_cond_init(&dataCond);
abs_thread_mutex_init(&pipeMut);
entries=0;
readPos=0;
writePos=0;
int i;
commandArray=new Command*[_COMMAND_ARRAY_SIZE];
for(i=0;i<_COMMAND_ARRAY_SIZE;i++) {
commandArray[i]=new Command(_COMMAND_NONE,0);
}
}
CommandPipe::~CommandPipe() {
abs_thread_cond_destroy(&spaceCond);
abs_thread_cond_destroy(&emptyCond);
abs_thread_cond_destroy(&dataCond);
abs_thread_mutex_destroy(&pipeMut);
int i;
for(i=0;i<_COMMAND_ARRAY_SIZE;i++) {
delete commandArray[i];
}
delete [] commandArray;
}
void CommandPipe::sendCommand(Command& cmd) {
sendCommand(cmd,true);
}
void CommandPipe::sendCommandNoWait(Command& cmd) {
sendCommand(cmd,false);
}
void CommandPipe::sendCommand(Command& cmd,int lWait) {
lockCommandPipe();
if (entries==_COMMAND_ARRAY_SIZE) {
waitForSpace();
}
cmd.copyTo(commandArray[writePos]);
writePos++;
if (writePos==_COMMAND_ARRAY_SIZE) {
writePos=0;
}
entries++;
// low water signal
if (entries==1) {
signalData();
}
unlockCommandPipe();
if (lWait) {
waitForEmptyQueue();
}
}
int CommandPipe::hasCommand(Command* dest) {
lockCommandPipe();
if (entries==0) {
unlockCommandPipe();
return false;
}
commandArray[readPos]->copyTo(dest);
readPos++;
if (readPos==_COMMAND_ARRAY_SIZE) {
readPos=0;
}
entries--;
// low water
if (entries==0) {
signalEmpty();
unlockCommandPipe();
return true;
}
// if we are on highwater, signal space
if (entries==_COMMAND_ARRAY_SIZE-1) {
signalSpace();
}
unlockCommandPipe();
return true;
}
void CommandPipe::waitForEmptyQueue() {
lockCommandPipe();
while (entries > 0) {
waitForEmpty();
}
unlockCommandPipe();
}
void CommandPipe::waitForCommand() {
lockCommandPipe();
while (entries == 0) {
waitForData();
}
unlockCommandPipe();
}
void CommandPipe::lockCommandPipe() {
abs_thread_mutex_lock(&pipeMut);
}
void CommandPipe::unlockCommandPipe() {
abs_thread_mutex_unlock(&pipeMut);
}
void CommandPipe::waitForSpace() {
abs_thread_cond_wait(&spaceCond,&pipeMut);
}
void CommandPipe::waitForEmpty() {
abs_thread_cond_wait(&emptyCond,&pipeMut);
}
void CommandPipe::waitForData() {
abs_thread_cond_wait(&dataCond,&pipeMut);
}
void CommandPipe::signalSpace() {
abs_thread_cond_signal(&spaceCond);
}
void CommandPipe::signalEmpty() {
abs_thread_cond_signal(&emptyCond);
}
void CommandPipe::signalData() {
abs_thread_cond_signal(&dataCond);
}