Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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);
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);
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__)