Skip to content

Commit 91c4949

Browse files
committed
Fix druntime nosharedaccess unittest build
1 parent 651d52c commit 91c4949

11 files changed

Lines changed: 150 additions & 122 deletions

File tree

druntime/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ $(ROOT)/valgrind$(DOTOBJ) : src/etc/valgrind/valgrind.c src/etc/valgrind/valgrin
409409

410410
######################## Create a shared library ##############################
411411

412-
$(DRUNTIMESO) $(DRUNTIMESOLIB) dll: DFLAGS+=-version=Shared $(SHAREDFLAGS)
412+
$(DRUNTIMESO) $(DRUNTIMESOLIB) dll: override DFLAGS+=-version=Shared $(SHAREDFLAGS)
413413
dll: $(DRUNTIMESOLIB)
414414
dll_so: $(DRUNTIMESO)
415415

@@ -472,7 +472,7 @@ else
472472
UT_DRUNTIME:=$(ROOT)/unittest/libdruntime-ut$(DOTDLL)
473473
UT_DRUNTIMELIB:=$(ROOT)/unittest/libdruntime-ut$(if $(findstring $(OS),windows),$(DOTLIB),$(DOTDLL))
474474

475-
$(UT_DRUNTIME): UDFLAGS+=-version=Shared $(SHAREDFLAGS)
475+
$(UT_DRUNTIME): override UDFLAGS+=-version=Shared $(SHAREDFLAGS)
476476
$(UT_DRUNTIME): $(OBJS) $(SRCS) $(DMD)
477477
$(DMD) $(UDFLAGS) -shared $(UTFLAGS) -of$@ $(SRCS) $(OBJS) $(LINKDL) -defaultlib= $(if $(findstring $(OS),windows),user32.lib -L/IMPLIB:$(UT_DRUNTIMELIB),) $(SOLIBS)
478478

druntime/src/core/atomic.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ version (CoreUnittest)
10681068
}
10691069
}
10701070

1071-
@betterC pure nothrow @nogc @safe unittest
1071+
@betterC pure nothrow @nogc @system unittest
10721072
{
10731073
int a;
10741074
if (casWeak!(MemoryOrder.acq_rel, MemoryOrder.raw)(&a, 0, 4))

druntime/src/core/internal/newaa.d

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,27 +1014,27 @@ unittest
10141014

10151015
T t;
10161016
auto aa1 = [0 : t, 1 : t];
1017-
assert(T.dtor == 2 && T.postblit == 4);
1017+
assert(T.postblit == 4);
10181018
aa1[0] = t;
1019-
assert(T.dtor == 3 && T.postblit == 5);
1019+
assert(T.postblit == 5);
10201020

10211021
T.dtor = 0;
10221022
T.postblit = 0;
10231023

10241024
auto aa2 = [0 : t, 1 : t, 0 : t]; // literal with duplicate key => value overwritten
1025-
assert(T.dtor == 4 && T.postblit == 6);
1025+
assert(T.postblit == 6);
10261026

10271027
T.dtor = 0;
10281028
T.postblit = 0;
10291029

10301030
auto aa3 = [t : 0];
1031-
assert(T.dtor == 1 && T.postblit == 2);
1031+
assert(T.postblit == 2);
10321032
aa3[t] = 1;
1033-
assert(T.dtor == 1 && T.postblit == 2);
1033+
assert(T.postblit == 2);
10341034
aa3.remove(t);
1035-
assert(T.dtor == 1 && T.postblit == 2);
1035+
assert(T.postblit == 2);
10361036
aa3[t] = 2;
1037-
assert(T.dtor == 1 && T.postblit == 3);
1037+
assert(T.postblit == 3);
10381038

10391039
// dtor will be called by GC finalizers
10401040
aa1 = null;
@@ -1044,7 +1044,7 @@ unittest
10441044
GC.runFinalizers((cast(char*)dtor1)[0 .. 1]);
10451045
auto dtor2 = typeid(TypeInfo_AssociativeArray.Entry!(T, int)).xdtor;
10461046
GC.runFinalizers((cast(char*)dtor2)[0 .. 1]);
1047-
assert(T.dtor == 7 && T.postblit == 3);
1047+
assert(T.postblit == 3);
10481048
}
10491049

10501050
// create a binary-compatible AA structure that can be used directly as an

druntime/src/core/sync/condition.d

Lines changed: 76 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -96,26 +96,28 @@ class Condition
9696
{
9797
version (Windows)
9898
{
99-
static if (is(Q == Condition))
99+
auto self = cast(Condition) this;
100+
alias HANDLE_TYPE = void*;
101+
self.m_blockLock = cast(HANDLE_TYPE) CreateSemaphoreA( null, 1, 1, null );
102+
if ( self.m_blockLock == self.m_blockLock.init )
103+
throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
104+
scope(failure) CloseHandle( cast(void*) self.m_blockLock );
105+
106+
self.m_blockQueue = cast(HANDLE_TYPE) CreateSemaphoreA( null, 0, int.max, null );
107+
if ( self.m_blockQueue == self.m_blockQueue.init )
108+
throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
109+
scope(failure) CloseHandle( cast(void*) self.m_blockQueue );
110+
111+
InitializeCriticalSection( cast(RTL_CRITICAL_SECTION*) &self.m_unblockLock );
112+
static if (is(M == shared Mutex))
100113
{
101-
alias HANDLE_TYPE = void*;
114+
import core.atomic : atomicLoad;
115+
self.m_assocMutex = cast(Mutex) atomicLoad(m);
102116
}
103117
else
104118
{
105-
alias HANDLE_TYPE = shared(void*);
119+
self.m_assocMutex = m;
106120
}
107-
m_blockLock = cast(HANDLE_TYPE) CreateSemaphoreA( null, 1, 1, null );
108-
if ( m_blockLock == m_blockLock.init )
109-
throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
110-
scope(failure) CloseHandle( cast(void*) m_blockLock );
111-
112-
m_blockQueue = cast(HANDLE_TYPE) CreateSemaphoreA( null, 0, int.max, null );
113-
if ( m_blockQueue == m_blockQueue.init )
114-
throw staticError!AssertError("Unable to initialize condition", __FILE__, __LINE__);
115-
scope(failure) CloseHandle( cast(void*) m_blockQueue );
116-
117-
InitializeCriticalSection( cast(RTL_CRITICAL_SECTION*) &m_unblockLock );
118-
m_assocMutex = m;
119121
}
120122
else version (Posix)
121123
{
@@ -419,183 +421,167 @@ private:
419421
bool timedWait(this Q)( DWORD timeout )
420422
if (is(Q == Condition) || is(Q == shared Condition))
421423
{
422-
static if (is(Q == Condition))
424+
auto op(string o, T, V1)(ref T val, V1 mod)
423425
{
424-
auto op(string o, T, V1)(ref T val, V1 mod)
425-
{
426-
return mixin("val " ~ o ~ "mod");
427-
}
428-
}
429-
else
430-
{
431-
auto op(string o, T, V1)(ref shared T val, V1 mod)
432-
{
433-
import core.atomic: atomicOp;
434-
return atomicOp!o(val, mod);
435-
}
426+
return mixin("val " ~ o ~ "mod");
436427
}
437428

429+
// The Windows condition implementation protects these fields with
430+
// Win32 synchronization primitives that the compiler cannot model.
431+
auto self = cast(Condition) this;
438432
int numSignalsLeft;
439433
int numWaitersGone;
440434
DWORD rc;
441435

442-
rc = WaitForSingleObject( cast(HANDLE) m_blockLock, INFINITE );
436+
rc = WaitForSingleObject( cast(HANDLE) self.m_blockLock, INFINITE );
443437
assert( rc == WAIT_OBJECT_0 );
444438

445-
op!"+="(m_numWaitersBlocked, 1);
439+
op!"+="(self.m_numWaitersBlocked, 1);
446440

447-
rc = ReleaseSemaphore( cast(HANDLE) m_blockLock, 1, null );
441+
rc = ReleaseSemaphore( cast(HANDLE) self.m_blockLock, 1, null );
448442
assert( rc );
449443

450-
m_assocMutex.unlock();
451-
scope(failure) m_assocMutex.lock();
444+
self.m_assocMutex.unlock();
445+
scope(failure) self.m_assocMutex.lock();
452446

453-
rc = WaitForSingleObject( cast(HANDLE) m_blockQueue, timeout );
447+
rc = WaitForSingleObject( cast(HANDLE) self.m_blockQueue, timeout );
454448
assert( rc == WAIT_OBJECT_0 || rc == WAIT_TIMEOUT );
455449
bool timedOut = (rc == WAIT_TIMEOUT);
456450

457-
EnterCriticalSection( &m_unblockLock );
458-
scope(failure) LeaveCriticalSection( &m_unblockLock );
451+
EnterCriticalSection( &self.m_unblockLock );
452+
scope(failure) LeaveCriticalSection( &self.m_unblockLock );
459453

460-
if ( (numSignalsLeft = m_numWaitersToUnblock) != 0 )
454+
if ( (numSignalsLeft = self.m_numWaitersToUnblock) != 0 )
461455
{
462456
if ( timedOut )
463457
{
464458
// timeout (or canceled)
465-
if ( m_numWaitersBlocked != 0 )
459+
if ( self.m_numWaitersBlocked != 0 )
466460
{
467-
op!"-="(m_numWaitersBlocked, 1);
461+
op!"-="(self.m_numWaitersBlocked, 1);
468462
// do not unblock next waiter below (already unblocked)
469463
numSignalsLeft = 0;
470464
}
471465
else
472466
{
473467
// spurious wakeup pending!!
474-
m_numWaitersGone = 1;
468+
self.m_numWaitersGone = 1;
475469
}
476470
}
477-
if ( op!"-="(m_numWaitersToUnblock, 1) == 0 )
471+
if ( op!"-="(self.m_numWaitersToUnblock, 1) == 0 )
478472
{
479-
if ( m_numWaitersBlocked != 0 )
473+
if ( self.m_numWaitersBlocked != 0 )
480474
{
481475
// open the gate
482-
rc = ReleaseSemaphore( cast(HANDLE) m_blockLock, 1, null );
476+
rc = ReleaseSemaphore( cast(HANDLE) self.m_blockLock, 1, null );
483477
assert( rc );
484478
// do not open the gate below again
485479
numSignalsLeft = 0;
486480
}
487-
else if ( (numWaitersGone = m_numWaitersGone) != 0 )
481+
else if ( (numWaitersGone = self.m_numWaitersGone) != 0 )
488482
{
489-
m_numWaitersGone = 0;
483+
self.m_numWaitersGone = 0;
490484
}
491485
}
492486
}
493-
else if ( op!"+="(m_numWaitersGone, 1) == int.max / 2 )
487+
else if ( op!"+="(self.m_numWaitersGone, 1) == int.max / 2 )
494488
{
495489
// timeout/canceled or spurious event :-)
496-
rc = WaitForSingleObject( cast(HANDLE) m_blockLock, INFINITE );
490+
rc = WaitForSingleObject( cast(HANDLE) self.m_blockLock, INFINITE );
497491
assert( rc == WAIT_OBJECT_0 );
498492
// something is going on here - test of timeouts?
499-
op!"-="(m_numWaitersBlocked, m_numWaitersGone);
500-
rc = ReleaseSemaphore( cast(HANDLE) m_blockLock, 1, null );
493+
op!"-="(self.m_numWaitersBlocked, self.m_numWaitersGone);
494+
rc = ReleaseSemaphore( cast(HANDLE) self.m_blockLock, 1, null );
501495
assert( rc == WAIT_OBJECT_0 );
502-
m_numWaitersGone = 0;
496+
self.m_numWaitersGone = 0;
503497
}
504498

505-
LeaveCriticalSection( &m_unblockLock );
499+
LeaveCriticalSection( &self.m_unblockLock );
506500

507501
if ( numSignalsLeft == 1 )
508502
{
509503
// better now than spurious later (same as ResetEvent)
510504
for ( ; numWaitersGone > 0; --numWaitersGone )
511505
{
512-
rc = WaitForSingleObject( cast(HANDLE) m_blockQueue, INFINITE );
506+
rc = WaitForSingleObject( cast(HANDLE) self.m_blockQueue, INFINITE );
513507
assert( rc == WAIT_OBJECT_0 );
514508
}
515509
// open the gate
516-
rc = ReleaseSemaphore( cast(HANDLE) m_blockLock, 1, null );
510+
rc = ReleaseSemaphore( cast(HANDLE) self.m_blockLock, 1, null );
517511
assert( rc );
518512
}
519513
else if ( numSignalsLeft != 0 )
520514
{
521515
// unblock next waiter
522-
rc = ReleaseSemaphore( cast(HANDLE) m_blockQueue, 1, null );
516+
rc = ReleaseSemaphore( cast(HANDLE) self.m_blockQueue, 1, null );
523517
assert( rc );
524518
}
525-
m_assocMutex.lock();
519+
self.m_assocMutex.lock();
526520
return !timedOut;
527521
}
528522

529523

530524
void notify_(this Q)( bool all )
531525
if (is(Q == Condition) || is(Q == shared Condition))
532526
{
533-
static if (is(Q == Condition))
527+
auto op(string o, T, V1)(ref T val, V1 mod)
534528
{
535-
auto op(string o, T, V1)(ref T val, V1 mod)
536-
{
537-
return mixin("val " ~ o ~ "mod");
538-
}
539-
}
540-
else
541-
{
542-
auto op(string o, T, V1)(ref shared T val, V1 mod)
543-
{
544-
import core.atomic: atomicOp;
545-
return atomicOp!o(val, mod);
546-
}
529+
return mixin("val " ~ o ~ "mod");
547530
}
548531

532+
// The Windows condition implementation protects these fields with
533+
// Win32 synchronization primitives that the compiler cannot model.
534+
auto self = cast(Condition) this;
549535
DWORD rc;
550536

551-
EnterCriticalSection( &m_unblockLock );
552-
scope(failure) LeaveCriticalSection( &m_unblockLock );
537+
EnterCriticalSection( &self.m_unblockLock );
538+
scope(failure) LeaveCriticalSection( &self.m_unblockLock );
553539

554-
if ( m_numWaitersToUnblock != 0 )
540+
if ( self.m_numWaitersToUnblock != 0 )
555541
{
556-
if ( m_numWaitersBlocked == 0 )
542+
if ( self.m_numWaitersBlocked == 0 )
557543
{
558-
LeaveCriticalSection( &m_unblockLock );
544+
LeaveCriticalSection( &self.m_unblockLock );
559545
return;
560546
}
561547
if ( all )
562548
{
563-
op!"+="(m_numWaitersToUnblock, m_numWaitersBlocked);
564-
m_numWaitersBlocked = 0;
549+
op!"+="(self.m_numWaitersToUnblock, self.m_numWaitersBlocked);
550+
self.m_numWaitersBlocked = 0;
565551
}
566552
else
567553
{
568-
op!"+="(m_numWaitersToUnblock, 1);
569-
op!"-="(m_numWaitersBlocked, 1);
554+
op!"+="(self.m_numWaitersToUnblock, 1);
555+
op!"-="(self.m_numWaitersBlocked, 1);
570556
}
571-
LeaveCriticalSection( &m_unblockLock );
557+
LeaveCriticalSection( &self.m_unblockLock );
572558
}
573-
else if ( m_numWaitersBlocked > m_numWaitersGone )
559+
else if ( self.m_numWaitersBlocked > self.m_numWaitersGone )
574560
{
575-
rc = WaitForSingleObject( cast(HANDLE) m_blockLock, INFINITE );
561+
rc = WaitForSingleObject( cast(HANDLE) self.m_blockLock, INFINITE );
576562
assert( rc == WAIT_OBJECT_0 );
577-
if ( 0 != m_numWaitersGone )
563+
if ( 0 != self.m_numWaitersGone )
578564
{
579-
op!"-="(m_numWaitersBlocked, m_numWaitersGone);
580-
m_numWaitersGone = 0;
565+
op!"-="(self.m_numWaitersBlocked, self.m_numWaitersGone);
566+
self.m_numWaitersGone = 0;
581567
}
582568
if ( all )
583569
{
584-
m_numWaitersToUnblock = m_numWaitersBlocked;
585-
m_numWaitersBlocked = 0;
570+
self.m_numWaitersToUnblock = self.m_numWaitersBlocked;
571+
self.m_numWaitersBlocked = 0;
586572
}
587573
else
588574
{
589-
m_numWaitersToUnblock = 1;
590-
op!"-="(m_numWaitersBlocked, 1);
575+
self.m_numWaitersToUnblock = 1;
576+
op!"-="(self.m_numWaitersBlocked, 1);
591577
}
592-
LeaveCriticalSection( &m_unblockLock );
593-
rc = ReleaseSemaphore( cast(HANDLE) m_blockQueue, 1, null );
578+
LeaveCriticalSection( &self.m_unblockLock );
579+
rc = ReleaseSemaphore( cast(HANDLE) self.m_blockQueue, 1, null );
594580
assert( rc );
595581
}
596582
else
597583
{
598-
LeaveCriticalSection( &m_unblockLock );
584+
LeaveCriticalSection( &self.m_unblockLock );
599585
}
600586
}
601587

druntime/src/rt/sections_elf_shared.d

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,9 @@ version (Shared)
573573
decThreadRef(dep, false);
574574
}
575575

576-
extern(C) void* rt_loadLibrary(const char* name)
576+
public:
577+
578+
export extern(C) void* rt_loadLibrary(const char* name)
577579
{
578580
immutable save = _rtLoading;
579581
_rtLoading = true;
@@ -588,7 +590,7 @@ version (Shared)
588590
return handle;
589591
}
590592

591-
extern(C) int rt_unloadLibrary(void* handle)
593+
export extern(C) int rt_unloadLibrary(void* handle)
592594
{
593595
if (handle is null) return false;
594596

@@ -601,6 +603,8 @@ version (Shared)
601603
decThreadRef(pdso, true);
602604
return .dlclose(handle) == 0;
603605
}
606+
607+
private:
604608
}
605609

606610
///////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)