1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /** 6 * Watchers register user's interest in some event. 7 * 8 * Copyright: Eugene Wissner 2016-2020. 9 * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, 10 * Mozilla Public License, v. 2.0). 11 * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) 12 * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/async/watcher.d, 13 * tanya/async/watcher.d) 14 */ 15 module tanya.async.watcher; 16 17 import tanya.async.loop; 18 import tanya.async.protocol; 19 import tanya.async.transport; 20 import tanya.container.buffer; 21 import tanya.container.list; 22 import tanya.memory.allocator; 23 import tanya.net.socket; 24 25 /** 26 * A watcher is an opaque structure that you allocate and register to record 27 * your interest in some event. 28 */ 29 abstract class Watcher 30 { 31 /// Whether the watcher is active. 32 bool active; 33 34 /** 35 * Invoke some action on event. 36 */ 37 void invoke() @nogc; 38 } 39 40 /** 41 * Socket watcher. 42 */ 43 abstract class SocketWatcher : Watcher 44 { 45 /// Watched socket. 46 protected Socket socket_; 47 48 /** 49 * Params: 50 * socket = Socket. 51 * 52 * Precondition: $(D_INLINECODE socket !is null) 53 */ 54 this(Socket socket) pure nothrow @safe @nogc 55 in 56 { 57 assert(socket !is null); 58 } 59 do 60 { 61 socket_ = socket; 62 } 63 64 /** 65 * Returns: Socket. 66 */ 67 @property Socket socket() pure nothrow @safe @nogc 68 { 69 return socket_; 70 } 71 } 72 73 /** 74 * Connection watcher. 75 */ 76 class ConnectionWatcher : SocketWatcher 77 { 78 /// Incoming connection queue. 79 DList!DuplexTransport incoming; 80 81 private Protocol delegate() @nogc protocolFactory; 82 83 /** 84 * Params: 85 * socket = Socket. 86 */ 87 this(Socket socket) @nogc 88 { 89 super(socket); 90 } 91 92 /** 93 * Params: 94 * P = Protocol should be used. 95 */ 96 void setProtocol(P : Protocol)() @nogc 97 { 98 this.protocolFactory = () @nogc => cast(Protocol) defaultAllocator.make!P; 99 } 100 101 /** 102 * Invokes new connection callback. 103 */ 104 override void invoke() @nogc 105 in 106 { 107 assert(protocolFactory !is null, "Protocol isn't set."); 108 } 109 do 110 { 111 for (; !this.incoming.empty; this.incoming.removeFront()) 112 { 113 this.incoming.front.protocol = protocolFactory(); 114 this.incoming.front.protocol.connected(this.incoming.front); 115 } 116 } 117 }