source: abuse/tags/pd/macabuse/imlib/port/unix/shm_fifo.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 2.3 KB
Line 
1
2#include <sys/ipc.h>
3#include <sys/shm.h>
4#include <signal.h>
5#include <stdlib.h>
6#include <stdio.h>
7
8//#include "dprint.hpp"
9#include "shm_fifo.hpp"
10
11int shm_fifo::read(void *buf, int size)
12{
13  unsigned char *b=(unsigned char *)buf;
14  int tread=0;
15  while (size)
16  {
17    while (fc->f_start==fc->f_end)
18    {
19      if (fc->nattached<2)
20        return tread;
21      sleep(0);
22    }
23
24    *b=data[fc->f_start];
25    if (fc->f_start==fc->size-1)
26      fc->f_start=0;
27    else fc->f_start++;
28    b++;
29    size--;
30    tread++;
31  }
32  return tread;
33}
34
35int shm_fifo::write(void *buf, int size)
36{
37  unsigned char *b=(unsigned char *)buf;
38  int twriten=0;
39  while (size)
40  {
41    while (fc->f_end==fc->f_start-1 || (fc->f_end==fc->size-1 && fc->f_start==0))   // wait to space to write
42    {
43      if (fc->nattached<2) return twriten;
44      sleep(0);
45    }
46
47    data[fc->f_end]=*b;
48    if (fc->f_end==fc->size)
49      fc->f_end=0;
50    else fc->f_end++;
51    b++;
52    twriten++;
53    size--;
54  }
55  return twriten;
56}
57
58int shm_fifo::ready_to_read()
59{
60  return fc->f_start!=fc->f_end;
61}
62
63shm_fifo::shm_fifo()
64{
65  shm_id=-1;
66}
67
68int shm_fifo::create(int size)
69{
70  if (shm_id==-1)
71  {
72    shm_id=shmget(IPC_PRIVATE,size+sizeof(fifo_control),IPC_CREAT);
73    if (shm_id<0) return 0;
74    fc=(fifo_control *)shmat(shm_id,0,0);
75    if (!fc)
76    {
77      shmctl(shm_id,IPC_RMID,NULL);
78      return 0;
79    }
80    data=(unsigned char *)(fc+1);   
81    fc->nattached=1;
82    fc->f_start=fc->f_end=0;            // clear buffer
83    fc->size=size;
84    return 1;
85  }
86 
87  dprintf("shm_fifo already created/attached\n");
88  return 0; 
89}
90
91
92int shm_fifo::wait_attach()
93{
94  while (fc->nattached==1); 
95  unsigned char on;
96  read(&on,1);
97  shmctl(shm_id,IPC_RMID,NULL);     // now that the other process has it, delete the shm id so memory gets freed on exit
98  return 1;
99}
100
101
102
103int shm_fifo::attach(int id)   // attach to already
104{
105  if (shm_id==-1)
106  {
107    fc=(fifo_control *)shmat(id,0,0); 
108    if (!fc)
109      return 0;
110    shm_id=id;
111    data=(unsigned char *)(fc+1);
112    fc->nattached++;               // notify entry
113    unsigned char on=1;
114    write(&on,1);                  // write one byte
115    while (ready_to_read());      // wait for it to get read
116    return 1;
117  }
118  return 0;
119}
120
121
122shm_fifo::~shm_fifo()
123{
124  if (shm_id!=-1)
125  {
126    fc->nattached--;
127    shmdt(fc);
128    shm_id=-1;
129  }
130}
131
Note: See TracBrowser for help on using the repository browser.