source: git/Singular/links/semaphore.c @ 6152da

spielwiese
Last change on this file since 6152da was 6152da, checked in by Hans Schoenemann <hannes@…>, 10 years ago
semphore.c: includes
  • Property mode set to 100644
File size: 3.1 KB
Line 
1
2
3
4
5#include <kernel/mod2.h>
6
7#ifdef HAVE_SIMPLEIPC
8#include <semaphore.h>
9#include <fcntl.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <sys/types.h>
15#include <unistd.h>
16
17
18# include "simpleipc.h"
19
20#include <Singular/cntrlc.h>
21#include <reporter/si_signals.h>
22
23
24
25// Not yet implemented: SYSV IPC Semaphores
26// They are more difficult to clean up after a process crash
27// but are supported more widely.
28
29sem_t *semaphore[SIPC_MAX_SEMAPHORES];
30int sem_acquired[SIPC_MAX_SEMAPHORES];
31
32/* return 1 on success,
33 *        0 if already initialized,
34 *       -1 for errors
35 */
36int sipc_semaphore_init(int id, int count)
37{
38  char buf[100];
39  sem_t *sem;
40  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES))
41    return -1;
42  // Already initialized?
43  if (semaphore[id])
44    return 0;
45  // to make it completely safe, we should generate a name
46  // from /dev/urandom.
47#if USE_SEM_INIT
48  // TODO: This should really use mapped memory so that processes
49  // can keep using the semaphore after fork + exec.
50  sem = malloc(sizeof(sem_t));
51  if (!sem)
52    return -1;
53  if (sem_init(sem, 1, count) < 0)
54  {
55    free(sem);
56    return -1;
57  }
58#else
59  sprintf(buf, "/%d:sem%d", getpid(), id);
60  sem_unlink(buf);
61  sem = sem_open(buf, O_CREAT, 0600, count);
62#endif
63  if (sem == SEM_FAILED || !sem)
64    return -1;
65  semaphore[id] = sem;
66#if !USE_SEM_INIT
67  sem_unlink(buf);
68#endif
69  return 1;
70}
71
72int sipc_semaphore_exists(int id)
73{
74  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES))  return -1;
75  return semaphore[id] != NULL;
76}
77
78int sipc_semaphore_acquire(int id)
79{
80  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
81  defer_shutdown++;
82  si_sem_wait(semaphore[id]);
83  sem_acquired[id]++;
84  defer_shutdown--;
85  if (!defer_shutdown && do_shutdown) m2_end(1);
86  return 1;
87}
88
89int sipc_semaphore_try_acquire(int id)
90{
91  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
92  defer_shutdown++;
93  int trywait = si_sem_trywait(semaphore[id]);
94  if (!trywait)
95  {
96    sem_acquired[id]++;
97  }
98  defer_shutdown--;
99  if (!defer_shutdown && do_shutdown) m2_end(1);
100  return !trywait;
101}
102
103int sipc_semaphore_release(int id)
104{
105  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
106  defer_shutdown++;
107  sem_post(semaphore[id]);
108  sem_acquired[id]--;
109  defer_shutdown--;
110  if (!defer_shutdown && do_shutdown) m2_end(1);
111  return 1;
112}
113
114int sipc_semaphore_get_value(int id)
115{
116  int val;
117  if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL))  return -1;
118  sem_getvalue(semaphore[id], &val);
119  return val;
120}
121
122int simpleipc_cmd(char *cmd, int id, int v)
123{
124  if (strcmp(cmd,"init")==0)
125    return sipc_semaphore_init(id,v);
126  else if (strcmp(cmd,"exists")==0)
127    return sipc_semaphore_exists(id);
128  else if (strcmp(cmd,"acquire")==0)
129    return  sipc_semaphore_acquire(id);
130  else if (strcmp(cmd,"try_acquire")==0)
131    return sipc_semaphore_try_acquire(id);
132  else if (strcmp(cmd,"release")==0)
133    return sipc_semaphore_release(id);
134  else if (strcmp(cmd,"get_value")==0)
135    return sipc_semaphore_get_value(id);
136  else printf("unknown\n");
137    return  -2;
138}
139#endif
Note: See TracBrowser for help on using the repository browser.