msq.win32.c
Go to the documentation of this file.
1 // Copyright (c) 2010-2016 The YP-Spur Authors, except where otherwise indicated.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif // HAVE_CONFIG_H
29 
30 #include <ipcommunication.h>
31 #include <utility.h>
32 
33 #if defined(__MINGW32__)
34 #include <windows.h>
35 #include <tchar.h>
36 
37 HANDLE g_shm = NULL;
38 void *g_shm_data;
39 HANDLE g_mutex = NULL;
40 
41 int msgget(key_t key, int msgflg)
42 {
43  TCHAR name[512];
44 
45  _stprintf(name, "MessageQueueShm%d", (int)key);
46  g_shm = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 8192, name);
47 
48  g_shm_data = (void *)MapViewOfFile(g_shm, FILE_MAP_ALL_ACCESS, 0, 0, 8192);
49 
50  _stprintf(name, "MessageQueueMutex%d", (int)key);
51  if (msgflg & IPC_CREAT)
52  {
53  g_mutex = CreateMutex(NULL, FALSE, name);
54  *((int32_t *)g_shm_data) = 0;
55  }
56  else
57  {
58  g_mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, name);
59  }
60  if (g_mutex == NULL)
61  {
62  return -1;
63  }
64 
65  return 1;
66 }
67 
68 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
69 {
70  char *pos;
71 
72  if (WaitForSingleObject(g_mutex, INFINITE) == WAIT_FAILED)
73  {
74  CloseHandle(g_mutex);
75  CloseHandle(g_shm);
76  return -1;
77  }
78 
79  msgsz += sizeof(long); // add size of msg_type
80 
81  pos = (char *)g_shm_data;
82  while (1)
83  {
84  int32_t size;
85 
86  size = *(int32_t *)pos;
87  if (size == 0)
88  break;
89 
90  pos += sizeof(int32_t) + size;
91  }
92 
93  if ((char *)pos + msgsz + sizeof(int32_t) - (char *)g_shm_data > 8192)
94  return 0;
95 
96  *((int32_t *)pos) = (int32_t)msgsz;
97  pos += sizeof(int32_t);
98  memcpy(pos, msgp, msgsz);
99  pos += msgsz;
100  *((int32_t *)pos) = 0;
101 
102  ReleaseMutex(g_mutex);
103 
104  return 1;
105 }
106 
107 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
108 {
109  char *pos;
110  char *pos_before;
111  char *pos_target;
112  int32_t readsize;
113 
114  msgsz += sizeof(long); // add size of msg_type
115 
116  readsize = 0;
117  while (1)
118  {
119  if (WaitForSingleObject(g_mutex, INFINITE) == WAIT_FAILED)
120  {
121  CloseHandle(g_mutex);
122  CloseHandle(g_shm);
123  return -1;
124  }
125 
126  pos = (char *)g_shm_data;
127  pos_target = NULL;
128  while (1)
129  {
130  int32_t size;
131  int32_t *ptype;
132 
133  size = *(int32_t *)pos;
134  if (size == 0)
135  break;
136 
137  pos_before = pos;
138  ptype = (int32_t *)(pos_before + sizeof(int32_t));
139  if (((*ptype == msgtyp && msgtyp > 0) || (*ptype <= -msgtyp && msgtyp < 0)) && !pos_target)
140  {
141  pos_target = pos_before;
142  }
143  pos += sizeof(int32_t) + size;
144  }
145  if (pos_target)
146  {
147  char *pos_next;
148  int32_t sizeleft;
149 
150  if (*((int32_t *)pos_target) < msgsz)
151  {
152  readsize = *((int32_t *)pos_target);
153  }
154  else
155  {
156  readsize = msgsz;
157  }
158  pos_next = pos_target + sizeof(int32_t) + *((int32_t *)pos_target);
159  sizeleft = pos - pos_next + 1;
160  memcpy(msgp, pos_target + sizeof(int32_t), readsize);
161  memcpy(pos_target, pos_next, sizeleft);
162  }
163 
164  ReleaseMutex(g_mutex);
165 
166  if (!(msgflg & IPC_NOWAIT) && !pos_target)
167  {
168  yp_usleep(5000);
169  continue;
170  }
171  break;
172  }
173  if (!pos_target)
174  return -1;
175 
176  return readsize;
177 }
178 
179 int msgctl(int msqid, int cmd, struct msqid_ds *buf)
180 {
181  switch (cmd)
182  {
183  case IPC_RMID:
184  if (g_shm)
185  CloseHandle(g_shm);
186  if (g_mutex)
187  CloseHandle(g_mutex);
188  return 1;
189  break;
190  case IPC_SET:
191  case IPC_STAT:
192  default:
193  break;
194  }
195  return -1;
196 }
197 
198 #endif // defined(__MINGW32__)
void yp_usleep(int usec)
Definition: utility.c:54


yp-spur
Author(s):
autogenerated on Sat May 11 2019 02:08:24