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 <QSharedMemory>
27 #include <QSystemSemaphore>
28 #include <QWriteLocker>
30 ///////////////////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////////////////
34 static const size_t g_lamexp_ipc_slots
= 128;
39 unsigned int reserved_1
;
40 unsigned int reserved_2
;
47 unsigned int pos_write
;
48 unsigned int pos_read
;
49 lamexp_ipc_data_t data
[g_lamexp_ipc_slots
];
53 ///////////////////////////////////////////////////////////////////////////////
55 ///////////////////////////////////////////////////////////////////////////////
62 char *semaphore_read_mutex
;
63 char *semaphore_write
;
64 char *semaphore_write_mutex
;
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}"
76 QSharedMemory
*sharedmem
;
77 QSystemSemaphore
*semaphore_read
;
78 QSystemSemaphore
*semaphore_read_mutex
;
79 QSystemSemaphore
*semaphore_write
;
80 QSystemSemaphore
*semaphore_write_mutex
;
85 ///////////////////////////////////////////////////////////////////////////////
87 ///////////////////////////////////////////////////////////////////////////////
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
)
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
));
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
));
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
));
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
));
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
)
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
));
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
));
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();
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
;
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();
220 void lamexp_ipc_read(unsigned int *command
, char* message
, size_t buffSize
)
222 QReadLocker
readLock(&g_lamexp_ipc_ptr
.lock
);
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
);
252 qWarning("Malformed IPC message, will be ignored");
258 ///////////////////////////////////////////////////////////////////////////////
260 ///////////////////////////////////////////////////////////////////////////////
262 extern "C" void _lamexp_global_init_ipcom(void)
264 LAMEXP_ZERO_MEMORY(g_lamexp_ipc_ptr
);
267 ///////////////////////////////////////////////////////////////////////////////
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
);