Advertisement
NovaYoshi

IPC stuff

Dec 17th, 2014
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.70 KB | None | 0 0
  1. typedef struct IPC_Message {
  2.   SDL_atomic_t Used;
  3.   int Id;
  4.   char *Text;
  5. } IPC_Message;
  6.  
  7. typedef struct IPC_Queue {
  8.   int Size;
  9.   SDL_atomic_t MakeId;
  10.   SDL_atomic_t UseId;
  11.   SDL_mutex *Mutex;
  12.   SDL_sem *Semaphore;
  13.   IPC_Message *Queue;
  14.   SDL_cond *Condition;
  15. } IPC_Queue;
  16.  
  17. int IPC_New(IPC_Queue *Out[], int Size, int Queues) {
  18.   for(int i=0; i<Queues; i++) {
  19.     Out[i] = (IPC_Queue*)calloc(1,sizeof(IPC_Queue));
  20.     if(!Out[i])
  21.       return 0;
  22.     Out[i]->Size = Size;
  23.     Out[i]->Queue = (IPC_Message*)calloc(Size,sizeof(IPC_Message));
  24.     Out[i]->Semaphore = SDL_CreateSemaphore(Size);
  25.     Out[i]->Mutex = SDL_CreateMutex();
  26.     Out[i]->Condition = SDL_CreateCond();
  27.   }
  28.   return 1;
  29. }
  30.  
  31. void IPC_Free(IPC_Queue *Holder[], int Queues) {
  32.   for(int i=0; i<Queues; i++) {
  33.     for(int j=0; j<Holder[i]->Size; j++)
  34.       if(Holder[i]->Queue[j].Text)
  35.         free(Holder[i]->Queue[j].Text);
  36.     free(Holder[i]->Queue);
  37.     SDL_DestroyMutex(Holder[i]->Mutex);
  38.     SDL_DestroySemaphore(Holder[i]->Semaphore);
  39.     SDL_DestroyCond(Holder[i]->Condition);
  40.     free(Holder[i]);
  41.   }
  42. }
  43.  
  44. void IPC_Write(IPC_Queue *Queue, const char *Text) {
  45.   SDL_LockMutex(Queue->Mutex);
  46.   SDL_SemWait(Queue->Semaphore);
  47.   for(int i=0; i<Queue->Size; i++)
  48.     if(!SDL_AtomicGet(&Queue->Queue[i].Used)) {
  49.       SDL_AtomicSet(&Queue->Queue[i].Used, 1);
  50.       // write text
  51.       Queue->Queue[i].Text = (char*)malloc(strlen(Text)+1);
  52.       strcpy(Queue->Queue[i].Text, Text);
  53.       // update id
  54.       Queue->Queue[i].Id = SDL_AtomicGet(&Queue->MakeId);
  55.       SDL_AtomicAdd(&Queue->MakeId, 1);
  56.       SDL_AtomicSet(&Queue->Queue[i].Used, 2);
  57.       SDL_UnlockMutex(Queue->Mutex);
  58.       SDL_CondSignal(Queue->Condition);
  59.       return;
  60.     }
  61.   // we shouldn't be able to get here, but if we do, unlock stuff
  62.   SDL_SemPost(Queue->Semaphore);
  63.   SDL_UnlockMutex(Queue->Mutex);
  64. }
  65.  
  66. char *IPC_Read(IPC_Queue *Queue, int Timeout) {
  67.   SDL_LockMutex(Queue->Mutex);
  68.   int Size = Queue->Size;
  69.   int MakeId = SDL_AtomicGet(&Queue->MakeId);
  70.   int UseId = SDL_AtomicGet(&Queue->UseId);
  71.   if(MakeId == UseId) {
  72.     int Result = SDL_CondWaitTimeout(Queue->Condition, Queue->Mutex, Timeout);
  73.     if(Result != 0) // zero means success
  74.       goto Fail;
  75.   }
  76.   if(UseId < MakeId) { // are there any items to read?
  77.     for(int i = 0; i < Size; i++)
  78.       if(SDL_AtomicGet(&Queue->Queue[i].Used) && (Queue->Queue[i].Id == UseId)) {
  79.         SDL_AtomicAdd(&Queue->UseId, 1);
  80.         char *Text = Queue->Queue[i].Text;
  81.         SDL_AtomicSet(&Queue->Queue[i].Used, 0);
  82.         SDL_SemPost(Queue->Semaphore);
  83.         SDL_UnlockMutex(Queue->Mutex);
  84.         return Text;
  85.       }
  86.   }
  87.  
  88. Fail:
  89.   SDL_UnlockMutex(Queue->Mutex);
  90.   return NULL;
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement