14# include <qt_windows.h>
20# define MAX_PATH PATH_MAX
28#if QT_CONFIG(sharedmemory)
30using namespace QtIpcCommon;
31using namespace Qt::StringLiterals;
33QSharedMemoryPrivate::~QSharedMemoryPrivate()
38inline void QSharedMemoryPrivate::constructBackend()
41 visit([](
auto p) { construct_at(p); });
44inline void QSharedMemoryPrivate::destructBackend()
46 visit([](
auto p) { std::destroy_at(p); });
49#if QT_CONFIG(systemsemaphore)
50inline QNativeIpcKey QSharedMemoryPrivate::semaphoreNativeKey()
const
52 if (isIpcSupported(IpcType::SharedMemory, QNativeIpcKey::Type::Windows)
53 && nativeKey.type() == QNativeIpcKey::Type::Windows) {
55 auto suffix =
"_sem"_L1;
56 QString semkey = nativeKey.nativeKey();
57 semkey.truncate(MAX_PATH - suffix.size() - 1);
59 return { semkey, QNativeIpcKey::Type::Windows };
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
104
105
106
107
108
109
110
111
112
114QSharedMemory::QSharedMemory(QObject *parent)
115 : QSharedMemory(QNativeIpcKey(), parent)
120
121
122
123
124
125
126
127
128QSharedMemory::QSharedMemory(
const QNativeIpcKey &key, QObject *parent)
129 : QObject(*
new QSharedMemoryPrivate(key.type()), parent)
135
136
137
138
139
140
141QSharedMemory::QSharedMemory(
const QString &key, QObject *parent)
142 : QSharedMemory(legacyNativeKey(key), parent)
147
148
149
150
151
152
153
154
155QSharedMemory::~QSharedMemory()
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183void QSharedMemory::setKey(
const QString &key)
185 setNativeKey(legacyNativeKey(key));
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228void QSharedMemory::setNativeKey(
const QNativeIpcKey &key)
231 if (key == d->nativeKey && key.isEmpty())
233 if (!isKeyTypeSupported(key.type())) {
234 d->setError(KeyError, tr(
"%1: unsupported key type")
235 .arg(
"QSharedMemory::setNativeKey"_L1));
242 if (key.type() == d->nativeKey.type()) {
247 d->destructBackend();
249 d->constructBackend();
253bool QSharedMemoryPrivate::initKey(SemaphoreAccessMode mode)
257#if QT_CONFIG(systemsemaphore)
258 const QString legacyKey = QNativeIpcKeyPrivate::legacyKey(nativeKey);
259 const QNativeIpcKey semKey = legacyKey.isEmpty()
260 ? semaphoreNativeKey()
261 : QSystemSemaphore::legacyNativeKey(legacyKey, nativeKey.type());
262 systemSemaphore.setNativeKey(semKey, 1, mode);
263 if (systemSemaphore.error() != QSystemSemaphore::NoError) {
264 QString function =
"QSharedMemoryPrivate::initKey"_L1;
265 errorString = QSharedMemory::tr(
"%1: unable to set key on lock (%2)")
266 .arg(function, systemSemaphore.errorString());
267 switch(systemSemaphore.error()) {
268 case QSystemSemaphore::PermissionDenied:
269 error = QSharedMemory::PermissionDenied;
271 case QSystemSemaphore::KeyError:
272 error = QSharedMemory::KeyError;
274 case QSystemSemaphore::AlreadyExists:
275 error = QSharedMemory::AlreadyExists;
277 case QSystemSemaphore::NotFound:
278 error = QSharedMemory::NotFound;
280 case QSystemSemaphore::OutOfResources:
281 error = QSharedMemory::OutOfResources;
283 case QSystemSemaphore::UnknownError:
285 error = QSharedMemory::UnknownError;
293 errorString = QString();
294 error = QSharedMemory::NoError;
299
300
301
302
303
304
305
306
307
308
309QString QSharedMemory::key()
const
311 Q_D(
const QSharedMemory);
312 return QNativeIpcKeyPrivate::legacyKey(d->nativeKey);
316
317
318
319
320
321
322
323
324
325
326
327
328QString QSharedMemory::nativeKey()
const
330 Q_D(
const QSharedMemory);
331 return d->nativeKey.nativeKey();
335
336
337
338
339
340
341
342
343
344
345
346
347QNativeIpcKey QSharedMemory::nativeIpcKey()
const
349 Q_D(
const QSharedMemory);
354
355
356
357
358
359
360
361
362
363bool QSharedMemory::create(qsizetype size, AccessMode mode)
366 QLatin1StringView function =
"QSharedMemory::create"_L1;
368#if QT_CONFIG(systemsemaphore)
369 if (!d->initKey(QSystemSemaphore::Create))
371 QSharedMemoryLocker lock(
this);
372 if (!d->nativeKey.isEmpty() && !d->tryLocker(&lock, function))
380 d->error = QSharedMemory::InvalidSize;
382 QSharedMemory::tr(
"%1: create size is less then 0").arg(function);
386 if (!d->create(size))
389 return d->attach(mode);
393
394
395
396
397
398
399
400
401qsizetype QSharedMemory::size()
const
403 Q_D(
const QSharedMemory);
408
409
410
411
412
413
414
415
416
417
420
421
422
423
424
425
426
427
428
429
430
431bool QSharedMemory::attach(AccessMode mode)
435 if (isAttached() || !d->initKey({}))
437#if QT_CONFIG(systemsemaphore)
438 QSharedMemoryLocker lock(
this);
439 if (!d->nativeKey.isEmpty() && !d->tryLocker(&lock,
"QSharedMemory::attach"_L1))
443 if (isAttached() || !d->handle())
446 return d->attach(mode);
450
451
452
453
454
455bool QSharedMemory::isAttached()
const
457 Q_D(
const QSharedMemory);
458 return (
nullptr != d->memory);
462
463
464
465
466
467
468
469
470
471bool QSharedMemory::detach()
477#if QT_CONFIG(systemsemaphore)
478 QSharedMemoryLocker lock(
this);
479 if (!d->nativeKey.isEmpty() && !d->tryLocker(&lock,
"QSharedMemory::detach"_L1))
487
488
489
490
491
492
493
494
495
496
497
498void *QSharedMemory::data()
505
506
507
508
509
510
511
512
513
514
515
516const void *QSharedMemory::constData()
const
518 Q_D(
const QSharedMemory);
523
524
525const void *QSharedMemory::data()
const
527 Q_D(
const QSharedMemory);
531#if QT_CONFIG(systemsemaphore)
533
534
535
536
537
538
539
540
541
542
543bool QSharedMemory::lock()
547 qWarning(
"QSharedMemory::lock: already locked");
550 if (d->systemSemaphore.acquire()) {
551 d->lockedByMe =
true;
554 const auto function =
"QSharedMemory::lock"_L1;
555 d->errorString = QSharedMemory::tr(
"%1: unable to lock").arg(function);
556 d->error = QSharedMemory::LockError;
561
562
563
564
565
566
567
568bool QSharedMemory::unlock()
573 d->lockedByMe =
false;
574 if (d->systemSemaphore.release())
576 const auto function =
"QSharedMemory::unlock"_L1;
577 d->errorString = QSharedMemory::tr(
"%1: unable to unlock").arg(function);
578 d->error = QSharedMemory::LockError;
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
613
614
615
616
617
618QSharedMemory::SharedMemoryError QSharedMemory::error()
const
620 Q_D(
const QSharedMemory);
625
626
627
628
629
630
631
632QString QSharedMemory::errorString()
const
634 Q_D(
const QSharedMemory);
635 return d->errorString;
638void QSharedMemoryPrivate::setUnixErrorString(QLatin1StringView function)
643 errorString = QSharedMemory::tr(
"%1: permission denied").arg(function);
644 error = QSharedMemory::PermissionDenied;
647 errorString = QSharedMemory::tr(
"%1: already exists").arg(function);
648 error = QSharedMemory::AlreadyExists;
651 errorString = QSharedMemory::tr(
"%1: doesn't exist").arg(function);
652 error = QSharedMemory::NotFound;
657 errorString = QSharedMemory::tr(
"%1: out of resources").arg(function);
658 error = QSharedMemory::OutOfResources;
661 errorString = QSharedMemory::tr(
"%1: unknown error: %2")
662 .arg(function, qt_error_string(errno));
663 error = QSharedMemory::UnknownError;
664#if defined QSHAREDMEMORY_DEBUG
665 qDebug() << errorString <<
"key" << key <<
"errno" << errno << EINVAL;
670bool QSharedMemory::isKeyTypeSupported(QNativeIpcKey::Type type)
672 if (!isIpcSupported(IpcType::SharedMemory, type))
674 using Variant =
decltype(QSharedMemoryPrivate::backend);
675 return Variant::staticVisit(type, [](
auto ptr) {
676 using Impl = std::decay_t<
decltype(*ptr)>;
677 return Impl::runtimeSupportCheck();
681QNativeIpcKey QSharedMemory::platformSafeKey(
const QString &key, QNativeIpcKey::Type type)
683 return QtIpcCommon::platformSafeKey(key, IpcType::SharedMemory, type);
686QNativeIpcKey QSharedMemory::legacyNativeKey(
const QString &key, QNativeIpcKey::Type type)
688 return QtIpcCommon::legacyPlatformSafeKey(key, IpcType::SharedMemory, type);
695#include "moc_qsharedmemory.cpp"