first commit
commit
9f4639e6ec
|
@ -0,0 +1,6 @@
|
|||
bin/
|
||||
obj/
|
||||
*.cbp
|
||||
*.layout
|
||||
*.depend
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
class ProcessSemaphore
|
||||
{
|
||||
public:
|
||||
/// action: 0 MustGet 1 MustCreateNew
|
||||
ProcessSemaphore(int key,int action=0,int default_value=1);
|
||||
bool isReady() const;
|
||||
int p(); /// wait
|
||||
int v(); /// notify
|
||||
int wait(); /// p
|
||||
int notify(); /// v
|
||||
~ProcessSemaphore();
|
||||
private:
|
||||
class impl;
|
||||
impl* _p;
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
/// Debug output
|
||||
void dprintf(const char* fmt,...);
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef _WIN32 /// Linux
|
||||
#include "SemaphoreWrapper.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
#include "log.h"
|
||||
|
||||
class ProcessSemaphore::impl
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
|
||||
int key;
|
||||
int status;
|
||||
bool created;
|
||||
};
|
||||
|
||||
static void _do_clean_up_semaphore(int key,int id)
|
||||
{
|
||||
if(semctl(id,0,IPC_RMID,0)<0)
|
||||
{
|
||||
log("Failed to destroy process semaphore (call semctl failed on key: %d, id: %d)",key,id);
|
||||
}
|
||||
}
|
||||
|
||||
ProcessSemaphore::ProcessSemaphore(int key,int action,int default_value) : _p(new impl)
|
||||
{
|
||||
if(_p)
|
||||
{
|
||||
_p->key=key;
|
||||
|
||||
_p->status=0;
|
||||
switch(action)
|
||||
{
|
||||
case 0:
|
||||
_p->id=semget(key,1,0666);
|
||||
break;
|
||||
case 1:
|
||||
_p->id=semget(key,1,0666|IPC_CREAT|IPC_EXCL);
|
||||
break;
|
||||
}
|
||||
|
||||
if(_p->id<0)
|
||||
{
|
||||
_p->status=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_p->status=1;
|
||||
|
||||
if(action==1) /// Created semaphore needs to be initialized
|
||||
{
|
||||
if(semctl(_p->id,0,SETVAL,1)>=0)
|
||||
{
|
||||
_p->status=2;
|
||||
_p->created=true;
|
||||
}
|
||||
}
|
||||
else /// Got a created semaphore
|
||||
{
|
||||
_p->status=2;
|
||||
_p->created=false;
|
||||
}
|
||||
|
||||
if(_p->status!=2) /// Semaphore does not reach ready level.
|
||||
{
|
||||
_do_clean_up_semaphore(key,_p->id);
|
||||
_p->status=0; /// Set status to empty(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessSemaphore::isReady() const
|
||||
{
|
||||
return _p&&_p->status==2;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::p()
|
||||
{
|
||||
struct sembuf b;
|
||||
b.sem_num=0;
|
||||
b.sem_op=-1;
|
||||
b.sem_flg=SEM_UNDO;
|
||||
if(semop(_p->id,&b,1)<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::v()
|
||||
{
|
||||
struct sembuf b;
|
||||
b.sem_num=0;
|
||||
b.sem_op=1;
|
||||
b.sem_flg=SEM_UNDO;
|
||||
if(semop(_p->id,&b,1)<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::wait()
|
||||
{
|
||||
return p();
|
||||
}
|
||||
|
||||
int ProcessSemaphore::notify()
|
||||
{
|
||||
return v();
|
||||
}
|
||||
|
||||
ProcessSemaphore::~ProcessSemaphore()
|
||||
{
|
||||
if(_p)
|
||||
{
|
||||
if(_p->created)
|
||||
{
|
||||
_do_clean_up_semaphore(_p->key,_p->id);
|
||||
}
|
||||
|
||||
delete _p;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /// End of Linux.
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
#include "SemaphoreWrapper.h"
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
|
||||
class ProcessSemaphore::impl
|
||||
{
|
||||
public:
|
||||
HANDLE h;
|
||||
|
||||
int status;
|
||||
};
|
||||
|
||||
ProcessSemaphore::ProcessSemaphore(int key, int action, int default_value) : _p(new impl)
|
||||
{
|
||||
if(_p)
|
||||
{
|
||||
_p->status=0;
|
||||
char buff[64];
|
||||
memset(buff,0,64);
|
||||
sprintf(buff,"LibSemaphoreWrapper_%d",key);
|
||||
|
||||
_p->h=CreateSemaphore(NULL,default_value,default_value,buff);
|
||||
|
||||
if(_p->h==NULL)
|
||||
{
|
||||
_p->status=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(action==1&&(GetLastError()==ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
CloseHandle(_p->h);
|
||||
_p->status=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_p->status=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessSemaphore::isReady() const
|
||||
{
|
||||
return _p&&_p->status==1;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::p()
|
||||
{
|
||||
DWORD ret=WaitForSingleObject(_p->h,INFINITE);
|
||||
if(ret==WAIT_OBJECT_0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(ret==WAIT_TIMEOUT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
int ProcessSemaphore::v()
|
||||
{
|
||||
ReleaseSemaphore(_p->h,1,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ProcessSemaphore::wait()
|
||||
{
|
||||
return p();
|
||||
}
|
||||
|
||||
int ProcessSemaphore::notify()
|
||||
{
|
||||
return v();
|
||||
}
|
||||
|
||||
ProcessSemaphore::~ProcessSemaphore()
|
||||
{
|
||||
if(_p)
|
||||
{
|
||||
if(isReady())
|
||||
{
|
||||
CloseHandle(_p->h);
|
||||
}
|
||||
|
||||
delete _p;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include "log.h"
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
using namespace std;
|
||||
|
||||
#ifdef DEBUG
|
||||
void dprintf(const char* fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
vprintf(fmt,ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#else
|
||||
void dprintf(const char* fmt,...)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
#include "SemaphoreWrapper.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main()
|
||||
{
|
||||
cout<<"Program Started."<<endl;
|
||||
|
||||
ProcessSemaphore s(666,1,2);
|
||||
cout<<"Status: "<<s.isReady()<<endl;
|
||||
|
||||
if(!s.isReady())
|
||||
{
|
||||
cout<<"Failed to create. Stop."<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cout<<"Start P"<<endl;
|
||||
s.p();
|
||||
cout<<"Done P"<<endl;
|
||||
|
||||
string x;
|
||||
getline(cin,x);
|
||||
|
||||
cout<<"Start V"<<endl;
|
||||
s.v();
|
||||
cout<<"Done V"<<endl;
|
||||
|
||||
cout<<"Program Finished. Press any key."<<endl;
|
||||
getline(cin,x);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue