1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
26 #include <MUtils/Global.h>
27 #include <MUtils/Exception.h>
30 #include <QSharedMemory>
31 #include <QSystemSemaphore>
32 #include <QWriteLocker>
34 ///////////////////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////////////////
38 static const size_t g_lamexp_ipc_slots = 128;
43 unsigned int reserved_1;
44 unsigned int reserved_2;
51 unsigned int pos_write;
52 unsigned int pos_read;
53 lamexp_ipc_data_t data[g_lamexp_ipc_slots];
57 ///////////////////////////////////////////////////////////////////////////////
59 ///////////////////////////////////////////////////////////////////////////////
66 char *semaphore_read_mutex;
67 char *semaphore_write;
68 char *semaphore_write_mutex;
72 "{21A68A42-6923-43bb-9CF6-64BF151942EE}",
73 "{7A605549-F58C-4d78-B4E5-06EFC34F405B}",
74 "{60AA8D04-F6B8-497d-81EB-0F600F4A65B5}",
75 "{726061D5-1615-4B82-871C-75FD93458E46}",
76 "{1A616023-AA6A-4519-8AF3-F7736E899977}"
80 QSharedMemory *sharedmem;
81 QSystemSemaphore *semaphore_read;
82 QSystemSemaphore *semaphore_read_mutex;
83 QSystemSemaphore *semaphore_write;
84 QSystemSemaphore *semaphore_write_mutex;
89 ///////////////////////////////////////////////////////////////////////////////
91 ///////////////////////////////////////////////////////////////////////////////
96 int lamexp_init_ipc(void)
98 QWriteLocker writeLock(&g_lamexp_ipc_ptr.lock);
100 if(g_lamexp_ipc_ptr.sharedmem && g_lamexp_ipc_ptr.semaphore_read && g_lamexp_ipc_ptr.semaphore_write && g_lamexp_ipc_ptr.semaphore_read_mutex && g_lamexp_ipc_ptr.semaphore_write_mutex)
105 g_lamexp_ipc_ptr.semaphore_read = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_read), 0);
106 g_lamexp_ipc_ptr.semaphore_write = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_write), 0);
107 g_lamexp_ipc_ptr.semaphore_read_mutex = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_read_mutex), 0);
108 g_lamexp_ipc_ptr.semaphore_write_mutex = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_write_mutex), 0);
110 if(g_lamexp_ipc_ptr.semaphore_read->error() != QSystemSemaphore::NoError)
112 QString errorMessage = g_lamexp_ipc_ptr.semaphore_read->errorString();
113 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read);
114 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write);
115 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
116 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
117 qFatal("Failed to create system smaphore: %s", MUTILS_UTF8(errorMessage));
120 if(g_lamexp_ipc_ptr.semaphore_write->error() != QSystemSemaphore::NoError)
122 QString errorMessage = g_lamexp_ipc_ptr.semaphore_write->errorString();
123 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read);
124 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write);
125 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
126 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
127 qFatal("Failed to create system smaphore: %s", MUTILS_UTF8(errorMessage));
130 if(g_lamexp_ipc_ptr.semaphore_read_mutex->error() != QSystemSemaphore::NoError)
132 QString errorMessage = g_lamexp_ipc_ptr.semaphore_read_mutex->errorString();
133 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read);
134 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write);
135 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
136 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
137 qFatal("Failed to create system smaphore: %s", MUTILS_UTF8(errorMessage));
140 if(g_lamexp_ipc_ptr.semaphore_write_mutex->error() != QSystemSemaphore::NoError)
142 QString errorMessage = g_lamexp_ipc_ptr.semaphore_write_mutex->errorString();
143 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read);
144 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write);
145 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
146 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
147 qFatal("Failed to create system smaphore: %s", MUTILS_UTF8(errorMessage));
151 g_lamexp_ipc_ptr.sharedmem = new QSharedMemory(QString(g_lamexp_ipc_uuid.sharedmem), NULL);
153 if(!g_lamexp_ipc_ptr.sharedmem->create(sizeof(lamexp_ipc_t)))
155 if(g_lamexp_ipc_ptr.sharedmem->error() == QSharedMemory::AlreadyExists)
157 g_lamexp_ipc_ptr.sharedmem->attach();
158 if(g_lamexp_ipc_ptr.sharedmem->error() == QSharedMemory::NoError)
164 QString errorMessage = g_lamexp_ipc_ptr.sharedmem->errorString();
165 MUTILS_DELETE(g_lamexp_ipc_ptr.sharedmem);
166 qFatal("Failed to attach to shared memory: %s", MUTILS_UTF8(errorMessage));
172 QString errorMessage = g_lamexp_ipc_ptr.sharedmem->errorString();
173 MUTILS_DELETE(g_lamexp_ipc_ptr.sharedmem);
174 qFatal("Failed to create shared memory: %s", MUTILS_UTF8(errorMessage));
179 memset(g_lamexp_ipc_ptr.sharedmem->data(), 0, sizeof(lamexp_ipc_t));
180 g_lamexp_ipc_ptr.semaphore_write->release(g_lamexp_ipc_slots);
181 g_lamexp_ipc_ptr.semaphore_read_mutex->release();
182 g_lamexp_ipc_ptr.semaphore_write_mutex->release();
190 void lamexp_ipc_send(unsigned int command, const char* message)
192 QReadLocker readLock(&g_lamexp_ipc_ptr.lock);
194 if(!g_lamexp_ipc_ptr.sharedmem || !g_lamexp_ipc_ptr.semaphore_read || !g_lamexp_ipc_ptr.semaphore_write || !g_lamexp_ipc_ptr.semaphore_read_mutex || !g_lamexp_ipc_ptr.semaphore_write_mutex)
196 MUTILS_THROW("Shared memory for IPC not initialized yet.");
199 lamexp_ipc_data_t ipc_data;
200 memset(&ipc_data, 0, sizeof(lamexp_ipc_data_t));
201 ipc_data.command = command;
205 strncpy_s(ipc_data.parameter, 4096, message, _TRUNCATE);
208 if(g_lamexp_ipc_ptr.semaphore_write->acquire())
210 if(g_lamexp_ipc_ptr.semaphore_write_mutex->acquire())
212 lamexp_ipc_t *ptr = reinterpret_cast<lamexp_ipc_t*>(g_lamexp_ipc_ptr.sharedmem->data());
213 memcpy(&ptr->data[ptr->pos_write], &ipc_data, sizeof(lamexp_ipc_data_t));
214 ptr->pos_write = (ptr->pos_write + 1) % g_lamexp_ipc_slots;
215 g_lamexp_ipc_ptr.semaphore_read->release();
216 g_lamexp_ipc_ptr.semaphore_write_mutex->release();
224 void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
226 QReadLocker readLock(&g_lamexp_ipc_ptr.lock);
231 if(!g_lamexp_ipc_ptr.sharedmem || !g_lamexp_ipc_ptr.semaphore_read || !g_lamexp_ipc_ptr.semaphore_write || !g_lamexp_ipc_ptr.semaphore_read_mutex || !g_lamexp_ipc_ptr.semaphore_write_mutex)
233 MUTILS_THROW("Shared memory for IPC not initialized yet.");
236 lamexp_ipc_data_t ipc_data;
237 memset(&ipc_data, 0, sizeof(lamexp_ipc_data_t));
239 if(g_lamexp_ipc_ptr.semaphore_read->acquire())
241 if(g_lamexp_ipc_ptr.semaphore_read_mutex->acquire())
243 lamexp_ipc_t *ptr = reinterpret_cast<lamexp_ipc_t*>(g_lamexp_ipc_ptr.sharedmem->data());
244 memcpy(&ipc_data, &ptr->data[ptr->pos_read], sizeof(lamexp_ipc_data_t));
245 ptr->pos_read = (ptr->pos_read + 1) % g_lamexp_ipc_slots;
246 g_lamexp_ipc_ptr.semaphore_write->release();
247 g_lamexp_ipc_ptr.semaphore_read_mutex->release();
249 if(!(ipc_data.reserved_1 || ipc_data.reserved_2))
251 *command = ipc_data.command;
252 strncpy_s(message, buffSize, ipc_data.parameter, _TRUNCATE);
256 qWarning("Malformed IPC message, will be ignored");
262 ///////////////////////////////////////////////////////////////////////////////
264 ///////////////////////////////////////////////////////////////////////////////
266 extern "C" void _lamexp_global_init_ipcom(void)
268 MUTILS_ZERO_MEMORY(g_lamexp_ipc_ptr);
271 ///////////////////////////////////////////////////////////////////////////////
273 ///////////////////////////////////////////////////////////////////////////////
275 extern "C" void _lamexp_global_free_ipcom(void)
277 if(g_lamexp_ipc_ptr.sharedmem)
279 g_lamexp_ipc_ptr.sharedmem->detach();
282 MUTILS_DELETE(g_lamexp_ipc_ptr.sharedmem);
283 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read);
284 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write);
285 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
286 MUTILS_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);