source: git/Singular/links/semaphore.c @ d600e18

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