msq.win32.c
Go to the documentation of this file.
00001 // Copyright (c) 2010-2016 The YP-Spur Authors, except where otherwise indicated.
00002 //
00003 // Permission is hereby granted, free of charge, to any person obtaining a copy
00004 // of this software and associated documentation files (the "Software"), to
00005 // deal in the Software without restriction, including without limitation the
00006 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00007 // sell copies of the Software, and to permit persons to whom the Software is
00008 // furnished to do so, subject to the following conditions:
00009 //
00010 // The above copyright notice and this permission notice shall be included in
00011 // all copies or substantial portions of the Software.
00012 //
00013 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00014 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00015 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00016 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00017 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00018 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00019 // SOFTWARE.
00020 
00021 #include <stdint.h>
00022 #include <stdio.h>
00023 #include <sys/types.h>
00024 #include <unistd.h>
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif  // HAVE_CONFIG_H
00029 
00030 #include <ipcommunication.h>
00031 #include <utility.h>
00032 
00033 #if defined(__MINGW32__)
00034 #include <windows.h>
00035 #include <tchar.h>
00036 
00037 HANDLE g_shm = NULL;
00038 void *g_shm_data;
00039 HANDLE g_mutex = NULL;
00040 
00041 int msgget(key_t key, int msgflg)
00042 {
00043   TCHAR name[512];
00044 
00045   _stprintf(name, "MessageQueueShm%d", (int)key);
00046   g_shm = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 8192, name);
00047 
00048   g_shm_data = (void *)MapViewOfFile(g_shm, FILE_MAP_ALL_ACCESS, 0, 0, 8192);
00049 
00050   _stprintf(name, "MessageQueueMutex%d", (int)key);
00051   if (msgflg & IPC_CREAT)
00052   {
00053     g_mutex = CreateMutex(NULL, FALSE, name);
00054     *((int32_t *)g_shm_data) = 0;
00055   }
00056   else
00057   {
00058     g_mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, name);
00059   }
00060   if (g_mutex == NULL)
00061   {
00062     return -1;
00063   }
00064 
00065   return 1;
00066 }
00067 
00068 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
00069 {
00070   char *pos;
00071 
00072   if (WaitForSingleObject(g_mutex, INFINITE) == WAIT_FAILED)
00073   {
00074     CloseHandle(g_mutex);
00075     CloseHandle(g_shm);
00076     return -1;
00077   }
00078 
00079   msgsz += sizeof(long);  // add size of msg_type
00080 
00081   pos = (char *)g_shm_data;
00082   while (1)
00083   {
00084     int32_t size;
00085 
00086     size = *(int32_t *)pos;
00087     if (size == 0)
00088       break;
00089 
00090     pos += sizeof(int32_t) + size;
00091   }
00092 
00093   if ((char *)pos + msgsz + sizeof(int32_t) - (char *)g_shm_data > 8192)
00094     return 0;
00095 
00096   *((int32_t *)pos) = (int32_t)msgsz;
00097   pos += sizeof(int32_t);
00098   memcpy(pos, msgp, msgsz);
00099   pos += msgsz;
00100   *((int32_t *)pos) = 0;
00101 
00102   ReleaseMutex(g_mutex);
00103 
00104   return 1;
00105 }
00106 
00107 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
00108 {
00109   char *pos;
00110   char *pos_before;
00111   char *pos_target;
00112   int32_t readsize;
00113 
00114   msgsz += sizeof(long);  // add size of msg_type
00115 
00116   readsize = 0;
00117   while (1)
00118   {
00119     if (WaitForSingleObject(g_mutex, INFINITE) == WAIT_FAILED)
00120     {
00121       CloseHandle(g_mutex);
00122       CloseHandle(g_shm);
00123       return -1;
00124     }
00125 
00126     pos = (char *)g_shm_data;
00127     pos_target = NULL;
00128     while (1)
00129     {
00130       int32_t size;
00131       int32_t *ptype;
00132 
00133       size = *(int32_t *)pos;
00134       if (size == 0)
00135         break;
00136 
00137       pos_before = pos;
00138       ptype = (int32_t *)(pos_before + sizeof(int32_t));
00139       if (((*ptype == msgtyp && msgtyp > 0) || (*ptype <= -msgtyp && msgtyp < 0)) && !pos_target)
00140       {
00141         pos_target = pos_before;
00142       }
00143       pos += sizeof(int32_t) + size;
00144     }
00145     if (pos_target)
00146     {
00147       char *pos_next;
00148       int32_t sizeleft;
00149 
00150       if (*((int32_t *)pos_target) < msgsz)
00151       {
00152         readsize = *((int32_t *)pos_target);
00153       }
00154       else
00155       {
00156         readsize = msgsz;
00157       }
00158       pos_next = pos_target + sizeof(int32_t) + *((int32_t *)pos_target);
00159       sizeleft = pos - pos_next + 1;
00160       memcpy(msgp, pos_target + sizeof(int32_t), readsize);
00161       memcpy(pos_target, pos_next, sizeleft);
00162     }
00163 
00164     ReleaseMutex(g_mutex);
00165 
00166     if (!(msgflg & IPC_NOWAIT) && !pos_target)
00167     {
00168       yp_usleep(5000);
00169       continue;
00170     }
00171     break;
00172   }
00173   if (!pos_target)
00174     return -1;
00175 
00176   return readsize;
00177 }
00178 
00179 int msgctl(int msqid, int cmd, struct msqid_ds *buf)
00180 {
00181   switch (cmd)
00182   {
00183     case IPC_RMID:
00184       if (g_shm)
00185         CloseHandle(g_shm);
00186       if (g_mutex)
00187         CloseHandle(g_mutex);
00188       return 1;
00189       break;
00190     case IPC_SET:
00191     case IPC_STAT:
00192     default:
00193       break;
00194   }
00195   return -1;
00196 }
00197 
00198 #endif  // defined(__MINGW32__)


yp-spur
Author(s):
autogenerated on Fri May 10 2019 02:52:19