Add C4droid implements
parent
bc07174c0e
commit
89e50ae269
|
@ -0,0 +1,224 @@
|
|||
#if (defined(_C4DROID_)&&!defined(_TRY_POSIX)) /// Generic Version
|
||||
|
||||
#include "SemaphoreWrapper.h"
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
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<int> 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;i<num_waiting;i++)
|
||||
{
|
||||
write(fd,&waiting[i],sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
static LockInfo getFrom(int fd)
|
||||
{
|
||||
lseek(fd,0L,SEEK_SET);
|
||||
|
||||
LockInfo x;
|
||||
read(fd,&x.total_value,sizeof(int));
|
||||
read(fd,&x.current_value,sizeof(int));
|
||||
|
||||
int num_waiting=x.waiting.size();
|
||||
read(fd,&num_waiting,sizeof(int));
|
||||
for(int i=0;i<num_waiting;i++)
|
||||
{
|
||||
int n;
|
||||
read(fd,&n,sizeof(int));
|
||||
x.waiting.push_back(n);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ProcessSemaphore::ProcessSemaphore(int key, int action, int default_value) : _p(new impl)
|
||||
{
|
||||
if(_p)
|
||||
{
|
||||
_p->status=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_TRUNC|O_EXCL);
|
||||
_p->owner=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_p->fd=open(_p->buff,O_RDWR);
|
||||
}
|
||||
|
||||
if(_p->fd>=0) /// Opened.
|
||||
{
|
||||
_p->status=2;
|
||||
|
||||
if(_p->owner)
|
||||
{
|
||||
/// Unlink it (delete on close) : Only owner will delete this file.
|
||||
unlink(_p->buff);
|
||||
|
||||
flock(_p->fd,LOCK_EX);
|
||||
LockInfo x;
|
||||
x.total_value=default_value;
|
||||
x.current_value=default_value;
|
||||
x.num_waiting=0;
|
||||
x.writeTo(_p->fd);
|
||||
flock(_p->fd,LOCK_UN);
|
||||
}
|
||||
}
|
||||
|
||||
if(_p->status!=0&&_p->status!=2) /// Clean up
|
||||
{
|
||||
close(_p->buff);
|
||||
_p->status=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProcessSemaphore::~ProcessSemaphore()
|
||||
{
|
||||
if(_p)
|
||||
{
|
||||
if(_p->status==2)
|
||||
{
|
||||
/// Close on delete.
|
||||
close(_p->buff);
|
||||
}
|
||||
|
||||
delete _p;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessSemaphore::isReady() const
|
||||
{
|
||||
return _p&&_p->status==2;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::p()
|
||||
{
|
||||
flock(_p->fd,LOCK_EX);
|
||||
LockInfo x=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);
|
||||
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;i<sz;i++)
|
||||
{
|
||||
if(x.waiting[i]==thisPid)
|
||||
{
|
||||
x.waiting.erase(x.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x.writeTo(_p->fd);
|
||||
/// 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(fd,LOCK_EX);
|
||||
LockInfo x=LockInfo::getFrom(_p->fd);
|
||||
x.current_value=x.current_value+1;
|
||||
x.writeTo(_p->fd);
|
||||
flock(fd,LOCK_UN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::wait()
|
||||
{
|
||||
return p();
|
||||
}
|
||||
|
||||
int ProcessSemaphore::notify()
|
||||
{
|
||||
return v();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /// End of try generic
|
|
@ -1,4 +1,4 @@
|
|||
#if (defined(__linux__)&&!defined(_TRY_POSIX)) /// Linux platform without trying posix.
|
||||
#if (defined(__linux__)&&!defined(_TRY_POSIX)&&!defined(_C4DROID_)) /// Linux platform without trying posix.
|
||||
|
||||
#include "SemaphoreWrapper.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue