Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit b0fe0f1

Browse files
committed
[core.sync.mutex] Add a @safe ddoc-ed test and a @nogc nothrow one
1 parent a3907a6 commit b0fe0f1

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

src/core/sync/mutex.d

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,85 @@ package:
294294
}
295295
}
296296

297+
///
298+
/* @safe nothrow -> see druntime PR 1726 */
299+
unittest
300+
{
301+
import core.thread : Thread;
302+
303+
class Resource
304+
{
305+
Mutex mtx;
306+
int cargo;
307+
308+
this() shared @safe nothrow
309+
{
310+
mtx = new shared Mutex();
311+
cargo = 42;
312+
}
313+
314+
void useResource() shared @safe nothrow @nogc
315+
{
316+
mtx.lock_nothrow();
317+
cargo++;
318+
mtx.unlock_nothrow();
319+
}
320+
}
321+
322+
shared Resource res = new shared Resource();
323+
324+
auto otherThread = new Thread(
325+
{
326+
foreach (i; 0 .. 10000)
327+
res.useResource();
328+
}).start();
329+
330+
foreach (i; 0 .. 10000)
331+
res.useResource();
332+
333+
otherThread.join();
297334

335+
assert (res.cargo == 20042);
336+
}
337+
338+
@system @nogc nothrow unittest
339+
{
340+
import core.stdc.stdlib : malloc, free;
341+
342+
void* p = malloc(__traits(classInstanceSize, Mutex));
343+
344+
auto ti = typeid(Mutex);
345+
p[0 .. ti.initializer.length] = ti.initializer[];
346+
347+
shared Mutex mtx = cast(shared(Mutex))p;
348+
mtx.__ctor();
349+
350+
mtx.lock_nothrow();
351+
352+
{ // test recursive locking
353+
mtx.tryLock_nothrow();
354+
mtx.unlock_nothrow();
355+
}
356+
357+
mtx.unlock_nothrow();
358+
359+
// In general destorying classes like this is not
360+
// safe, but since we know that the only base class
361+
// of Mutex is Object and it doesn't have a dtor
362+
// we can simply call the non-virtual __dtor() here.
363+
364+
// Ok to cast away shared because destruction
365+
// should happen only from a single thread.
366+
(cast(Mutex)mtx).__dtor();
367+
368+
// Verify that the underlying implementation has been destroyed
369+
// by checking that locking is not possible. This assumes
370+
// that the underlying implementation is well behaved
371+
// and makes the object non-lockable upon destruction.
372+
assert(!mtx.tryLock_nothrow());
373+
374+
free(cast(void*)mtx);
375+
}
298376

299377
unittest
300378
{

0 commit comments

Comments
 (0)