From dba01ce870165fd8d8a5fea921cb31f7c4e8c25f Mon Sep 17 00:00:00 2001 From: Comment Date: Mon, 10 Dec 2012 19:30:27 +0000 Subject: fixed race condition in asterisk driver --- ofAsterisk/src/Asterisk.cpp | 121 ++++++++++++++++++++++++++++---------------- ofAsterisk/src/Asterisk.h | 25 +++++---- 2 files changed, 90 insertions(+), 56 deletions(-) (limited to 'ofAsterisk') diff --git a/ofAsterisk/src/Asterisk.cpp b/ofAsterisk/src/Asterisk.cpp index b78678e..fc9dc7a 100755 --- a/ofAsterisk/src/Asterisk.cpp +++ b/ofAsterisk/src/Asterisk.cpp @@ -33,25 +33,28 @@ gameQ has 1 calls (max unlimited) in 'rrmemory' strategy (8s holdtime, 50s talkt void Asterisk::threadedFunction(){ - while( isThreadRunning() != 0 ){ - FILE *f = popen("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"queue show gameQ\"'", "re"); - int fn=fileno(f); - char buf[1000]; - ssize_t r = read(fn, buf, 1000); - pclose(f); - string msg=string(buf); - //received data is always a command ACKNOWLEDGEMENT - if (msg.compare(0,5,"gameQ")==0) { - vector lines; - split(msg,'\n',lines); - queued=0; - for (int i=4;i lines; + split(msg,'\n',lines); + queued=0; + for (int i=4;i0) startThread(true, false); // blocking, verbose + if (statusPollMillis>0) startThread(false, false); // blocking, verbose } -void Asterisk::startGame(){ - if (!isPlaying&&queued) { - cmd("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"devstate change Custom:GAME NOT_INUSE\"'"); - printf("Asterisk: attempting to dequeue\n"); - state=WAITING; - } +void Asterisk::startGame(){ + //if (lock()) { + if (state==ASTERISK_IDLE&&queued) { + cmd("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"devstate change Custom:GAME NOT_INUSE\"'"); + printf("Asterisk: attempting to dequeue\n"); + } + //unlock(); + //} } void Asterisk::endGame(string score){ printf("Asterisk: request hangup %s\n",playerCode.c_str()); - if (isPlaying) { - cmd("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"database put GAME statuscode "+score+"\"'"); + if (state==ASTERISK_PLAYING) { + //cmd("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"database put GAME statuscode "+score+"\"'"); string emsg="ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"hangup request "+playerCode+"\"'"; - cmd(emsg); + scmd(emsg); printf("Asterisk: hanging up %s\n",playerCode.c_str()); - state=WAITING; - isPlaying=false; + state=ASTERISK_IDLE; } } void Asterisk::cmd(string s) { - //non blocking command for anync messages - file = popen(s.c_str(), "re"); + //non blocking command for anync messages + //pclose(file); always closing before open crashes + printf("open file\n"); + file = popen(s.c_str(), "re"); //"e" seems necessary for non blocking but with it getting crash when dequeuing. can't seem to trace it filenum=fileno(file); - fcntl(filenum, F_SETFL, O_NONBLOCK); -} + fcntl(filenum, F_SETFL, O_NONBLOCK); + state=ASTERISK_WAITING; +} + +void Asterisk::scmd(string s) { + //non blocking command for anync messages + //pclose(file); always closing before open crashes + printf("open file\n"); + file = popen(s.c_str(), "re"); //"e" seems necessary for non blocking but with it getting crash when dequeuing. can't seem to trace it + filenum=fileno(file); + fcntl(filenum, F_SETFL, O_NONBLOCK); + printf("close file\n"); + pclose(file); +} + + +/*Child process PID: 4265 +Program received signal SIGABRT, Aborted. +In __GI_raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 () +Cannot open file: /home/tim/workspace/VFxmas/vfg/iofclose.c +*/ + int Asterisk::update(){ //capture stdin response from popen - if (state==WAITING||state==STARTING) { + if (state==ASTERISK_WAITING) { char buf[100]; ssize_t r = read(filenum, buf, 1000); //if (r == -1 && errno == EAGAIN) //no data yet //else - if (r > 0) { + if (r > 0) { + //is it here? + printf("close file\n"); pclose(file); string msg=string(buf); - state=IDLE; + state=ASTERISK_IDLE; //received data is always a command ACKNOWLEDGEMENT //can never issue a new one until last one returns? if (msg.compare(0,8,"Changing")==0) { printf("player dequeued\n"); - state==PLAYING; - isPlaying=true; + state=ASTERISK_STARTING; } else { printf("stdin says: %s\n",buf); @@ -127,15 +153,20 @@ int Asterisk::update(){ //printf("Asterisk: %s\n",msg.c_str()); if (msg.length()>3) { //printf("status msg: %s\n",msg.c_str()); - if (msg.substr(0,5)=="Local") { - state=PLAYING; + if (msg.substr(0,6)=="Hangup") { + state=ASTERISK_IDLE; + return ASTERISK_GAMEOVER; + } + if (msg.substr(0,5)=="Local"&&state==ASTERISK_STARTING) { + state=ASTERISK_PLAYING; playerCode=msg.substr(0,msg.length()-1); printf("Asterisk: game started: code %s\n",playerCode.c_str()); - return 1000; + return ASTERISK_GAMESTARTED; } return 0; } else { + //message length of <3 is a key return ofToInt(msg); } } diff --git a/ofAsterisk/src/Asterisk.h b/ofAsterisk/src/Asterisk.h index 5033a5c..fb6097c 100755 --- a/ofAsterisk/src/Asterisk.h +++ b/ofAsterisk/src/Asterisk.h @@ -4,10 +4,12 @@ #include "ofMain.h" #include "ofxNetwork.h" -#define IDLE 0 -#define WAITING 1 -#define STARTING 2 -#define PLAYING 3 +#define ASTERISK_IDLE 0 +#define ASTERISK_WAITING 1 +#define ASTERISK_STARTING 2 +#define ASTERISK_PLAYING 3 +#define ASTERISK_GAMESTARTED 1000 +#define ASTERISK_GAMEOVER 1001 class Asterisk: public ofThread @@ -15,27 +17,27 @@ class Asterisk: public ofThread public: Asterisk(){ } - + void start(){ - + } void stop(){ stopThread(); } //-------------------------- - + void setup(string passcode="1111",int millis=1000); virtual ~Asterisk(); void startGame(); void endGame(string score); int update(); int state; - bool isPlaying; int queued; protected: - void cmd(string s); + void cmd(string s); + void scmd(string s); void threadedFunction(); private: int startTime; @@ -43,8 +45,9 @@ class Asterisk: public ofThread int filenum; ofxUDPManager udpConnection; string playerCode; - int statusPollMillis; - + int statusPollMillis; + + }; #endif // ASTERISK_H -- cgit v1.2.3