root/lang/c/friendsd/shm.c @ 32953

Revision 15618, 3.5 kB (checked in by kazuho, 5 years ago)

initial import

Line 
1#include <stdio.h>
2#include <sys/types.h>
3#include <sys/ipc.h>
4#include <sys/shm.h>
5#include <signal.h>
6
7#define KEY_DEF ((key_t)7221)
8#define INTERVAL 50000 /* by useconds */
9
10extern int shmStat( void );
11extern char *shmOpen( int size );
12static int newShm( int key, int size );
13extern int shmClose( void );
14extern void shmWrite( void );
15extern void shmRead( void );
16extern void shmReset( void );
17extern int getShmVersion( void );
18extern int setShmDebug( int mode );
19extern int getShmDebug( void );
20extern int setShmOwner( int new_id );
21extern int getShmOwner( void );
22
23static int id = -1;
24
25struct FLAGS {
26  int write;
27  int wait;
28  int read;
29  int version;
30  int debug;
31  int ownerID;
32};
33static volatile struct FLAGS *flags;
34
35int shmStat( void ) {
36  struct shmid_ds buf;
37 
38  if( shmctl( id, IPC_STAT, &buf ) ) {
39    fprintf( stderr, "Couldn't obtain shm data.\n" );
40    fflush( stderr );
41    return( 1 );
42  }
43  fprintf( stderr, "       SHM Connection: %d.\n", buf.shm_nattch );
44  fflush( stderr );
45  return( 0 );
46}
47
48char *shmOpen( int size ) {
49  int x;
50  char *r;
51 
52  if( size ) {
53    for( x = 0; x < 10; x++ )
54      if( EOF != ( id = newShm( KEY_DEF + x, size ) ) )
55        goto ON_SUCCEED;
56    goto ON_ERROR;
57  } else
58    goto ON_SUCCEED;
59 ON_SUCCEED:
60  if( -1 == ( int )( flags = ( struct FLAGS * )shmat( id, ( char * )NULL, 0 ) ) ) {
61    fprintf( stderr, "Couldn't allocate shared memory.\n" );
62    return( NULL );
63  }
64  if( getShmDebug() )
65    shmStat();
66  return( ( ( char * )flags ) + sizeof( struct FLAGS ) );
67 ON_ERROR:
68  return( NULL );
69}
70
71int newShm( int key, int size ) {
72  int r;
73  struct FLAGS *tmpflags;
74  size += sizeof( struct FLAGS );
75  if( EOF == ( r = shmget( key, size, IPC_CREAT | IPC_EXCL | 0660 ) ) )
76    return( EOF );
77 
78  tmpflags = ( struct FLAGS * )shmat( r, ( char * )NULL, 0 );
79  tmpflags->write = 0;
80  tmpflags->read = 0;
81  tmpflags->wait = 0;
82  tmpflags->version = 0;
83  tmpflags->debug = 0;
84  tmpflags->ownerID = getpid();
85  shmdt( tmpflags );
86  return( r );
87}
88
89int shmClose() {
90  struct shmid_ds d;
91  int ret, f;
92 
93  if( getShmDebug() ) {
94    fprintf( stderr, "        shmClose()\n" );
95    fflush( stderr );
96  }
97  if( getpid() == flags->ownerID )
98    return( shmctl( id, IPC_RMID, &d ) );
99  else {
100    f = getShmDebug(); /* done because shm is going to be removed */
101    ret = shmdt( flags );
102    if( f )
103      shmStat();
104    return( ret );
105  }
106}
107
108void shmEnter( char *mode ) {
109  int waitTime;
110 
111  if( !strcmp( mode, "w" ) ) {
112    flags->wait++;
113    for( waitTime = 0; ; waitTime++ ) {
114      if( !flags->write && !flags->read )
115        break;
116      usleep( INTERVAL );
117    }
118    flags->write++;
119  } else {
120    for( waitTime = 0; ; waitTime++ ) {
121      if( !flags->wait )
122        break;
123      usleep( INTERVAL );
124    }
125    flags->read++;
126  }
127  if( getShmDebug() ) {
128    fprintf( stderr, "        shmEnter( \"%s\" ): %d:%d:%d(w:r:wait)\n", mode, flags->write, flags->read, waitTime );
129    fflush( stderr );
130  }
131}
132
133void shmLeave( char *mode ) {
134  if( !strcmp( mode, "w" ) ) {
135    flags->write = 0;
136    flags->wait--;
137    flags->version++;
138  } else
139    flags->read--;
140  if( getShmDebug() ) {
141    fprintf( stderr, "        shmLeave( \"%s\" ): %d:%d(w:r)\n", mode, flags->write, flags->read );
142    fflush( stderr );
143  }
144}
145
146int getShmVersion() {
147  return( flags->version );
148}
149
150int setShmDebug( int mode ) {
151  flags->debug = mode;
152  return( flags->debug );
153}
154
155int getShmDebug() {
156  return( flags->debug );
157}
158
159int setShmOwner( int new_id ) {
160  int ret = flags->ownerID;
161  flags->ownerID = new_id;
162  return( ret );
163}
164
165int getShmOwner() {
166  return( flags->ownerID );
167}
Note: See TracBrowser for help on using the browser.