Fixed "mailto:" links in about dialog box.
[LameXP.git] / src / Global_IPC.cpp
blob23cc6ed869d02d115a8637e54ba7b2250b45e5fe
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
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 ///////////////////////////////////////////////////////////////////////////////
23 #include "Global.h"
25 //Qt includes
26 #include <QSharedMemory>
27 #include <QSystemSemaphore>
28 #include <QWriteLocker>
30 ///////////////////////////////////////////////////////////////////////////////
31 // TYPES
32 ///////////////////////////////////////////////////////////////////////////////
34 static const size_t g_lamexp_ipc_slots = 128;
36 typedef struct
38 unsigned int command;
39 unsigned int reserved_1;
40 unsigned int reserved_2;
41 char parameter[4096];
43 lamexp_ipc_data_t;
45 typedef struct
47 unsigned int pos_write;
48 unsigned int pos_read;
49 lamexp_ipc_data_t data[g_lamexp_ipc_slots];
51 lamexp_ipc_t;
53 ///////////////////////////////////////////////////////////////////////////////
54 // GLOBAL VARS
55 ///////////////////////////////////////////////////////////////////////////////
57 //Shared memory
58 static const struct
60 char *sharedmem;
61 char *semaphore_read;
62 char *semaphore_read_mutex;
63 char *semaphore_write;
64 char *semaphore_write_mutex;
66 g_lamexp_ipc_uuid =
68 "{21A68A42-6923-43bb-9CF6-64BF151942EE}",
69 "{7A605549-F58C-4d78-B4E5-06EFC34F405B}",
70 "{60AA8D04-F6B8-497d-81EB-0F600F4A65B5}",
71 "{726061D5-1615-4B82-871C-75FD93458E46}",
72 "{1A616023-AA6A-4519-8AF3-F7736E899977}"
74 static struct
76 QSharedMemory *sharedmem;
77 QSystemSemaphore *semaphore_read;
78 QSystemSemaphore *semaphore_read_mutex;
79 QSystemSemaphore *semaphore_write;
80 QSystemSemaphore *semaphore_write_mutex;
81 QReadWriteLock lock;
83 g_lamexp_ipc_ptr;
85 ///////////////////////////////////////////////////////////////////////////////
86 // GLOBAL FUNCTIONS
87 ///////////////////////////////////////////////////////////////////////////////
90 * Initialize IPC
92 int lamexp_init_ipc(void)
94 QWriteLocker writeLock(&g_lamexp_ipc_ptr.lock);
96 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)
98 return 0;
101 g_lamexp_ipc_ptr.semaphore_read = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_read), 0);
102 g_lamexp_ipc_ptr.semaphore_write = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_write), 0);
103 g_lamexp_ipc_ptr.semaphore_read_mutex = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_read_mutex), 0);
104 g_lamexp_ipc_ptr.semaphore_write_mutex = new QSystemSemaphore(QString(g_lamexp_ipc_uuid.semaphore_write_mutex), 0);
106 if(g_lamexp_ipc_ptr.semaphore_read->error() != QSystemSemaphore::NoError)
108 QString errorMessage = g_lamexp_ipc_ptr.semaphore_read->errorString();
109 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read);
110 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write);
111 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
112 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
113 qFatal("Failed to create system smaphore: %s", QUTF8(errorMessage));
114 return -1;
116 if(g_lamexp_ipc_ptr.semaphore_write->error() != QSystemSemaphore::NoError)
118 QString errorMessage = g_lamexp_ipc_ptr.semaphore_write->errorString();
119 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read);
120 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write);
121 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
122 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
123 qFatal("Failed to create system smaphore: %s", QUTF8(errorMessage));
124 return -1;
126 if(g_lamexp_ipc_ptr.semaphore_read_mutex->error() != QSystemSemaphore::NoError)
128 QString errorMessage = g_lamexp_ipc_ptr.semaphore_read_mutex->errorString();
129 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read);
130 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write);
131 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
132 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
133 qFatal("Failed to create system smaphore: %s", QUTF8(errorMessage));
134 return -1;
136 if(g_lamexp_ipc_ptr.semaphore_write_mutex->error() != QSystemSemaphore::NoError)
138 QString errorMessage = g_lamexp_ipc_ptr.semaphore_write_mutex->errorString();
139 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read);
140 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write);
141 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
142 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);
143 qFatal("Failed to create system smaphore: %s", QUTF8(errorMessage));
144 return -1;
147 g_lamexp_ipc_ptr.sharedmem = new QSharedMemory(QString(g_lamexp_ipc_uuid.sharedmem), NULL);
149 if(!g_lamexp_ipc_ptr.sharedmem->create(sizeof(lamexp_ipc_t)))
151 if(g_lamexp_ipc_ptr.sharedmem->error() == QSharedMemory::AlreadyExists)
153 g_lamexp_ipc_ptr.sharedmem->attach();
154 if(g_lamexp_ipc_ptr.sharedmem->error() == QSharedMemory::NoError)
156 return 1;
158 else
160 QString errorMessage = g_lamexp_ipc_ptr.sharedmem->errorString();
161 LAMEXP_DELETE(g_lamexp_ipc_ptr.sharedmem);
162 qFatal("Failed to attach to shared memory: %s", QUTF8(errorMessage));
163 return -1;
166 else
168 QString errorMessage = g_lamexp_ipc_ptr.sharedmem->errorString();
169 LAMEXP_DELETE(g_lamexp_ipc_ptr.sharedmem);
170 qFatal("Failed to create shared memory: %s", QUTF8(errorMessage));
171 return -1;
175 memset(g_lamexp_ipc_ptr.sharedmem->data(), 0, sizeof(lamexp_ipc_t));
176 g_lamexp_ipc_ptr.semaphore_write->release(g_lamexp_ipc_slots);
177 g_lamexp_ipc_ptr.semaphore_read_mutex->release();
178 g_lamexp_ipc_ptr.semaphore_write_mutex->release();
180 return 0;
184 * IPC send message
186 void lamexp_ipc_send(unsigned int command, const char* message)
188 QReadLocker readLock(&g_lamexp_ipc_ptr.lock);
190 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)
192 THROW("Shared memory for IPC not initialized yet.");
195 lamexp_ipc_data_t ipc_data;
196 memset(&ipc_data, 0, sizeof(lamexp_ipc_data_t));
197 ipc_data.command = command;
199 if(message)
201 strncpy_s(ipc_data.parameter, 4096, message, _TRUNCATE);
204 if(g_lamexp_ipc_ptr.semaphore_write->acquire())
206 if(g_lamexp_ipc_ptr.semaphore_write_mutex->acquire())
208 lamexp_ipc_t *ptr = reinterpret_cast<lamexp_ipc_t*>(g_lamexp_ipc_ptr.sharedmem->data());
209 memcpy(&ptr->data[ptr->pos_write], &ipc_data, sizeof(lamexp_ipc_data_t));
210 ptr->pos_write = (ptr->pos_write + 1) % g_lamexp_ipc_slots;
211 g_lamexp_ipc_ptr.semaphore_read->release();
212 g_lamexp_ipc_ptr.semaphore_write_mutex->release();
218 * IPC read message
220 void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
222 QReadLocker readLock(&g_lamexp_ipc_ptr.lock);
224 *command = 0;
225 message[0] = '\0';
227 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)
229 THROW("Shared memory for IPC not initialized yet.");
232 lamexp_ipc_data_t ipc_data;
233 memset(&ipc_data, 0, sizeof(lamexp_ipc_data_t));
235 if(g_lamexp_ipc_ptr.semaphore_read->acquire())
237 if(g_lamexp_ipc_ptr.semaphore_read_mutex->acquire())
239 lamexp_ipc_t *ptr = reinterpret_cast<lamexp_ipc_t*>(g_lamexp_ipc_ptr.sharedmem->data());
240 memcpy(&ipc_data, &ptr->data[ptr->pos_read], sizeof(lamexp_ipc_data_t));
241 ptr->pos_read = (ptr->pos_read + 1) % g_lamexp_ipc_slots;
242 g_lamexp_ipc_ptr.semaphore_write->release();
243 g_lamexp_ipc_ptr.semaphore_read_mutex->release();
245 if(!(ipc_data.reserved_1 || ipc_data.reserved_2))
247 *command = ipc_data.command;
248 strncpy_s(message, buffSize, ipc_data.parameter, _TRUNCATE);
250 else
252 qWarning("Malformed IPC message, will be ignored");
258 ///////////////////////////////////////////////////////////////////////////////
259 // INITIALIZATION
260 ///////////////////////////////////////////////////////////////////////////////
262 extern "C" void _lamexp_global_init_ipcom(void)
264 LAMEXP_ZERO_MEMORY(g_lamexp_ipc_ptr);
267 ///////////////////////////////////////////////////////////////////////////////
268 // FINALIZATION
269 ///////////////////////////////////////////////////////////////////////////////
271 extern "C" void _lamexp_global_free_ipcom(void)
273 if(g_lamexp_ipc_ptr.sharedmem)
275 g_lamexp_ipc_ptr.sharedmem->detach();
278 LAMEXP_DELETE(g_lamexp_ipc_ptr.sharedmem);
279 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read);
280 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write);
281 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_read_mutex);
282 LAMEXP_DELETE(g_lamexp_ipc_ptr.semaphore_write_mutex);