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 }