vibe.core.driver 3/7(42%) line coverage

      
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
3886
3944
400
410
420
430
440
450
460
470
481
490
500
510
520
530
540
550
560
570
580
590
600
610
620
630
640
650
660
670
680
690
700
710
720
730
740
750
760
770
780
790
800
810
820
830
840
850
860
870
880
890
900
910
920
930
940
950
960
970
980
990
1000
1010
1020
1030
1040
1050
1060
1070
1080
1090
1100
1110
1120
1130
1140
1150
1160
1170
1180
1190
1200
1210
1220
1230
1240
1250
1260
1270
1280
1290
1300
1310
1320
1330
1340
1350
1360
1370
1380
1390
1400
1410
1420
1430
1440
1450
1460
1470
1480
1490
1500
1510
1520
1530
1540
1550
1560
1570
1580
1590
1600
1610
1620
1630
1640
1650
1660
1670
1680
1690
1700
1710
1720
1730
1740
1750
1760
1770
1780
1790
1800
1810
1820
1830
1840
1850
1860
1870
1880
1890
1900
1910
1920
1930
1940
1950
1960
1970
1980
1990
2000
2010
2020
2030
2040
2050
2060
2070
2080
2090
2100
2110
2120
2130
2140
2150
2160
2170
2180
2190
2200
2210
2220
2230
2240
2250
2260
2270
2280
2290
2300
2310
2320
2330
2340
2350
2360
2370
2380
2390
2400
2410
2420
2430
2440
2450
2460
2470
2480
2490
2500
2510
2520
2530
2540
2550
2560
2570
2580
2590
2600
2610
2620
2630
2640
2650
2660
2670
2680
2690
2700
2710
2720
2730
2740
2750
2760
2770
2780
2790
2800
/** Contains interfaces and enums for asynchronous drivers. At the lowest level of Vibe.d sits a library which handle all the asynchronous I/O operations. There are currently 3 supported I/O backend: libasync, libevent and libev. This module define the interface such a library must conform with to work with Vibe.d Copyright: © 2012-2015 RejectedSoftware e.K. Authors: Sönke Ludwig License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. */ module vibe.core.driver; public import vibe.core.file; public import vibe.core.net; public import vibe.core.path; public import vibe.core.sync; public import vibe.core.stream; public import vibe.core.task; import core.time; import std.exception; version (VibeUseNativeDriverType) { import vibe.core.drivers.native; alias StoredEventDriver = NativeEventDriver; } else alias StoredEventDriver = EventDriver; /** Returns the active event driver */ StoredEventDriver getEventDriver(bool ignore_unloaded = false) @safe nothrow { assert(ignore_unloaded || s_driver !is null, "No event driver loaded. Did the vibe.core.core module constructor run?"); return s_driver; } /// private package void setupEventDriver(DriverCore core_) { version (VibeUseNativeDriverType) {} else import vibe.core.drivers.native; s_driver = new NativeEventDriver(core_); } package void deleteEventDriver() { if (s_driver) { s_driver.dispose(); destroy(s_driver); s_driver = null; } } private { StoredEventDriver s_driver; } /** Interface for all evented I/O implementations. This is the low level interface for all event based functionality. It is not intended to be used directly by users of the library. */ interface EventDriver { @safe: /** Frees all resources of the driver and prepares it for consumption by the GC. Note that the driver will not be usable after calling this method. Any further calls are illegal and result in undefined behavior. */ void dispose() /*nothrow*/; /** Starts the event loop. The loop will continue to run until either no more event listeners are active or until exitEventLoop() is called. */ int runEventLoop() /*nothrow*/; /* Processes all outstanding events, potentially blocking to wait for the first event. */ int runEventLoopOnce() /*nothrow*/; /** Processes all outstanding events if any, does not block. */ bool processEvents() /*nothrow*/; /** Exits any running event loop. */ void exitEventLoop() /*nothrow*/; /** Opens a file on disk with the speficied file mode. */ FileStream openFile(Path path, FileMode mode); /** Starts watching a directory for changes. */ DirectoryWatcher watchDirectory(Path path, bool recursive); /** Resolves the given host name or IP address string. 'host' can be a DNS name (if use_dns is set) or an IPv4 or IPv6 address string. */ NetworkAddress resolveHost(string host, ushort family, bool use_dns); /** Establiches a tcp connection on the specified host/port. */ TCPConnection connectTCP(NetworkAddress address, NetworkAddress bind_address); /** Listens on the specified port and interface for TCP connections. 'bind_address' must be an IPv4 or IPv6 address string corresponding to a local network interface. conn_callback is called for every incoming connection, each time from a new task. */ TCPListener listenTCP(ushort port, void delegate(TCPConnection conn) @safe conn_callback, string bind_address, TCPListenOptions options); /** Creates a new UDP socket and sets the specified address/port as the destination for packets. If a bind port is specified, the socket will be able to receive UDP packets on that port. Otherwise, a random bind port is chosen. */ UDPConnection listenUDP(ushort port, string bind_address = "0.0.0.0"); /** Creates a new manually triggered event. */ ManualEvent createManualEvent() nothrow; /** Creates an event for waiting on a non-bocking file handle. */ FileDescriptorEvent createFileDescriptorEvent(int file_descriptor, FileDescriptorEvent.Trigger triggers, FileDescriptorEvent.Mode mode); /** Creates a new timer. The timer can be started by calling rearmTimer() with a timeout. The initial reference count is 1, use releaseTimer to free all resources associated with the timer. */ size_t createTimer(void delegate() @safe callback); /// Increases the reference count by one. void acquireTimer(size_t timer_id); /// Decreases the reference count by one. void releaseTimer(size_t timer_id); /// Queries if the timer is currently active. bool isTimerPending(size_t timer_id); /// Resets the timeout of the timer. void rearmTimer(size_t timer_id, Duration dur, bool periodic); /// Stops the timer. void stopTimer(size_t timer_id) nothrow; /// Waits for the pending timer to expire. void waitTimer(size_t timer_id); } /** Provides an event driver with core functions for task/fiber control. */ interface DriverCore { @safe: /** Sets an exception to be thrown on the next call to $(D yieldForEvent). Note that this only has an effect if $(D yieldForEvent) is called outside of a task. To throw an exception in a task, use the $(D event_exception) parameter to $(D resumeTask). */ @property void eventException(Exception e); /** Yields execution until the event loop receives an event. Throws: May throw an $(D InterruptException) if the task got interrupted using $(D vibe.core.task.Task.interrupt()). Rethrows any exception that is passed to the $(D resumeTask) call that wakes up the task. */ void yieldForEvent() @safe; /** Yields execution until the event loop receives an event. Throws: This method doesn't throw. Any exceptions, such as $(D InterruptException) or an exception passed to $(D resumeTask), are stored and thrown on the next call to $(D yieldForEvent). */ void yieldForEventDeferThrow() nothrow @safe; /** Resumes the given task. This function may only be called outside of a task to resume a yielded task. The optional $(D event_exception) will be thrown in the context of the resumed task. See_also: $(D yieldAndResumeTask) */ void resumeTask(Task task, Exception event_exception = null) @safe nothrow; /** Yields the current task and resumes another one. This is the same as $(D resumeTask), but also works from within a task. If called from a task, that task will be yielded first before resuming the other one. Throws: May throw an `InterruptException` if the calling task gets interrupted using `Task.interrupt()`. See_also: $(D resumeTask) */ void yieldAndResumeTask(Task task, Exception event_exception = null) @safe; /** Notifies the core that all events have been processed. This should be called by the driver whenever the event queue has been fully processed. */ void notifyIdle(); bool isScheduledForResume(Task t); } /** Generic file descriptor event. This kind of event can be used to wait for events on a non-blocking file descriptor. Note that this can usually only be used on socket based file descriptors. */ interface FileDescriptorEvent { @safe: /** Event mask selecting the kind of events to listen for. */ enum Trigger { none = 0, /// Match no event (invalid value) read = 1<<0, /// React on read-ready events write = 1<<1, /// React on write-ready events any = read|write /// Match any kind of event } /** Event waiting mode. */ enum Mode { nonPersistent, /// Indicates that the event is non-persistent persistent, /// Indicates that the event is persistent edgeTriggered /// Indicates that the event should be edge-triggered } /** Waits for the selected event to occur. Params: which = Optional event mask to react only on certain events timeout = Maximum time to wait for an event Returns: If events occurs, returns a mask of these events. If the timeout expired, returns the `Trigger.none` */ Trigger wait(Trigger which = Trigger.any); /// ditto Trigger wait(Duration timeout, Trigger which = Trigger.any); }