1 /*
2 *Copyright (C) 2018 Laurent Tréguier
3 *
4 *This file is part of DLS.
5 *
6 *DLS is free software: you can redistribute it and/or modify
7 *it under the terms of the GNU General Public License as published by
8 *the Free Software Foundation, either version 3 of the License, or
9 *(at your option) any later version.
10 *
11 *DLS 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.
15 *
16 *You should have received a copy of the GNU General Public License
17 *along with DLS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 module dls.util.disposable_fiber;
22
23 import core.thread : Fiber;
24
25 class FiberDisposedException : Exception
26 {
27 this()
28 {
29 super("Fiber disposed");
30 }
31 }
32
33 class DisposableFiber : Fiber
34 {
35 static bool safeMode;
36 private bool _disposed;
37
38 static DisposableFiber getThis()
39 {
40 const thisFiber = Fiber.getThis();
41 assert(typeid(thisFiber) == typeid(DisposableFiber));
42 return cast(DisposableFiber) thisFiber;
43 }
44
45 static void yield()
46 {
47 if (safeMode)
48 {
49 return;
50 }
51
52 Fiber.yield();
53
54 if (getThis()._disposed)
55 {
56 throw new FiberDisposedException();
57 }
58 }
59
60 this(void delegate() dg)
61 {
62 size_t pageSize;
63
64 version (Windows)
65 {
66 import core.sys.windows.winbase : GetSystemInfo, SYSTEM_INFO;
67
68 SYSTEM_INFO info;
69 GetSystemInfo(&info);
70 pageSize = cast(size_t) info.dwPageSize;
71 }
72 else version (Posix)
73 {
74 import core.sys.posix.unistd : _SC_PAGESIZE, sysconf;
75
76 pageSize = cast(size_t) sysconf(_SC_PAGESIZE);
77 }
78 else
79 {
80 pageSize = 4096;
81 }
82
83 super(dg, pageSize * 32);
84 }
85
86 void dispose()
87 {
88 _disposed = true;
89 }
90 }