source: git/Singular/links/semaphore.c @ 094ceb

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