#if (defined(_C4DROID_)&&!defined(_TRY_POSIX)) /// Generic Version #include "SemaphoreWrapper.h" #include #include #include #include #include #include #include #include #include #include using namespace std; class ProcessSemaphore::impl { public: char buff[256]; int fd; int status; bool owner; struct LockInfo { public: int total_value; int current_value; vector waiting; LockInfo() { total_value=0; current_value=0; } void writeTo(int fd) const { lseek(fd,0L,SEEK_SET); write(fd,&total_value,sizeof(int)); write(fd,¤t_value,sizeof(int)); int num_waiting=waiting.size(); write(fd,&num_waiting,sizeof(int)); for(int i=0;istatus=0; _p->owner=false; memset(_p->buff,0,256); sprintf(_p->buff,"LibSemaphoreWrapper_%d",key); if(action==1) { _p->fd=open(_p->buff,O_RDWR|O_CREAT|O_EXCL,0666); _p->owner=true; } else { _p->fd=open(_p->buff,O_RDWR,0666); } if(_p->fd>=0) /// Opened. { _p->status=2; if(_p->owner) { flock(_p->fd,LOCK_EX); impl::LockInfo x; x.total_value=default_value; x.current_value=default_value; x.writeTo(_p->fd); flock(_p->fd,LOCK_UN); } } else { perror("Failed to open file. "); } if(_p->status!=0&&_p->status!=2) /// Clean up { close(_p->fd); _p->status=0; } } } ProcessSemaphore::~ProcessSemaphore() { if(_p) { if(_p->status==2) { if(_p->owner) { /// Unlink it (delete on close) : Only owner will delete this file. unlink(_p->buff); } /// Close on delete. close(_p->fd); } delete _p; } } bool ProcessSemaphore::isReady() const { return _p&&_p->status==2; } int ProcessSemaphore::p() { flock(_p->fd,LOCK_EX); impl::LockInfo x=impl::LockInfo::getFrom(_p->fd); if(x.current_value<=0) { int thisPid=getpid(); x.waiting.push_back(thisPid); x.writeTo(_p->fd); /* /// wait for signal... typedef void (*fnvi)(int); _global_process_semaphore_value=0; fnvi old=signal(SIGUSR1,_global_process_semaphore_handler); */ flock(_p->fd,LOCK_UN); /// Sleep For 1 Second. sleep(1); while(1) { flock(_p->fd,LOCK_EX); x=impl::LockInfo::getFrom(_p->fd); if(x.current_value>0) /// Someone has released resource! { x.current_value=x.current_value-1; int sz=x.waiting.size(); for(int i=0;ifd); /// Pass! flock(_p->fd,LOCK_UN); break; } else /// Nothing happened... { flock(_p->fd,LOCK_UN); /// Sleep for 1 second. sleep(1); } } return 0; } else { x.current_value=x.current_value-1; x.writeTo(_p->fd); flock(_p->fd,LOCK_UN); /// Pass Operation P. return 0; } } int ProcessSemaphore::v() { flock(_p->fd,LOCK_EX); impl::LockInfo x=impl::LockInfo::getFrom(_p->fd); x.current_value=x.current_value+1; x.writeTo(_p->fd); flock(_p->fd,LOCK_UN); return 0; } int ProcessSemaphore::wait() { return p(); } int ProcessSemaphore::notify() { return v(); } #endif /// End of try generic