1 /******************************************************************************* 2 3 Classes used by the EpollSelectDispatcher to manage the set of registered 4 clients. 5 6 Copyright: 7 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 8 All rights reserved. 9 10 License: 11 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 12 Alternatively, this file may be distributed under the terms of the Tango 13 3-Clause BSD License (see LICENSE_BSD.txt for details). 14 15 *******************************************************************************/ 16 17 module ocean.io.select.selector.RegisteredClients; 18 19 20 21 22 import ocean.io.select.client.model.ISelectClient; 23 24 import ocean.util.container.map.Set; 25 26 debug ( ISelectClient ) import ocean.io.Stdout : Stderr; 27 28 29 30 31 /******************************************************************************* 32 33 Base class for a set of registered clients, with methods to add & remove 34 clients, and to tell how many clients are currently registered. When a 35 client is added or removed from the set its registered() or 36 unergistered() method, respectively, is called automatically. 37 38 *******************************************************************************/ 39 40 public abstract class IRegisteredClients 41 { 42 /*************************************************************************** 43 44 Adds a client to the set of registered clients. Calls the client's 45 registered() method, then calls the abstract add_() method. 46 47 Params: 48 client = client to add 49 50 ***************************************************************************/ 51 52 final public void opOpAssign ( string op : "+" ) ( ISelectClient client ) 53 { 54 debug ( ISelectClient ) Stderr.formatln("{} :: Registered", client).flush(); 55 client.registered(); 56 this.add_(client); 57 } 58 59 abstract protected void add_ ( ISelectClient client ); 60 61 /*************************************************************************** 62 63 Removes a client from the set of registered clients. Calls the client's 64 unregistered() method, then calls the abstract remove_() method. 65 66 Params: 67 client = client to remove 68 69 ***************************************************************************/ 70 71 final public void opOpAssign ( string op : "-" ) ( ISelectClient client ) 72 { 73 debug ( ISelectClient ) Stderr.formatln("{} :: Unregistered", client).flush(); 74 client.unregistered(); 75 this.remove_(client); 76 } 77 78 abstract protected void remove_ ( ISelectClient client ); 79 80 /*************************************************************************** 81 82 Returns: 83 the number of clients currently registered 84 85 ***************************************************************************/ 86 87 abstract public size_t length ( ); 88 } 89 90 91 /******************************************************************************* 92 93 Class to keep track of how many clients are registered. 94 95 *******************************************************************************/ 96 97 public final class ClientCount : IRegisteredClients 98 { 99 /*************************************************************************** 100 101 Number of clients registered. 102 103 ***************************************************************************/ 104 105 private size_t count; 106 107 /*************************************************************************** 108 109 Adds a client to the set. 110 111 Params: 112 c = client to add 113 114 ***************************************************************************/ 115 116 protected override void add_ ( ISelectClient c ) 117 { 118 this.count++; 119 } 120 121 /*************************************************************************** 122 123 Removes a client from the set. 124 125 Params: 126 c = client to remove 127 128 ***************************************************************************/ 129 130 protected override void remove_ ( ISelectClient c ) 131 { 132 this.count--; 133 } 134 135 /*************************************************************************** 136 137 Returns: 138 the number of clients currently registered 139 140 ***************************************************************************/ 141 142 public override size_t length ( ) 143 { 144 return this.count; 145 } 146 } 147 148 149 /******************************************************************************* 150 151 Class to keep track of a set of registered clients, including the 152 capacity to iterate over them. This class is used only in debug builds, 153 where it is useful to be able to tell exactly which clients are registered. 154 155 *******************************************************************************/ 156 157 public final class ClientSet : IRegisteredClients 158 { 159 /*************************************************************************** 160 161 Set of clients. 162 163 ***************************************************************************/ 164 165 static private class Clients : Set!(ISelectClient) 166 { 167 /*********************************************************************** 168 169 Estimated maximum number of clients, used by the super class to 170 determine the number of buckets in the set. 171 172 ***********************************************************************/ 173 174 static immutable max_clients_estimate = 1000; 175 176 /*********************************************************************** 177 178 Private constructor, prevents instantiation from the outside. 179 180 ***********************************************************************/ 181 182 private this ( ) 183 { 184 super(this.max_clients_estimate); 185 } 186 187 /*********************************************************************** 188 189 Hashing function, required by super class. Determines which set 190 bucket is responsible for the specified client. 191 192 Params: 193 c = client to get hash for 194 195 Returns: 196 hash for client (the class reference is used) 197 198 ***********************************************************************/ 199 200 public override hash_t toHash ( in ISelectClient c ) 201 { 202 return cast(hash_t)cast(void*)c; 203 } 204 } 205 206 private Clients clients; 207 208 /*************************************************************************** 209 210 Constructor. 211 212 ***************************************************************************/ 213 214 public this ( ) 215 { 216 this.clients = new Clients; 217 } 218 219 /*************************************************************************** 220 221 Adds a client to the set. 222 223 Params: 224 c = client to add 225 226 ***************************************************************************/ 227 228 public override void add_ ( ISelectClient c ) 229 { 230 this.clients.put(c); 231 } 232 233 /*************************************************************************** 234 235 Removes a client from the set. 236 237 Params: 238 c = client to remove 239 240 ***************************************************************************/ 241 242 public override void remove_ ( ISelectClient c ) 243 { 244 this.clients.remove(c); 245 } 246 247 /*************************************************************************** 248 249 Returns: 250 the number of clients currently registered 251 252 ***************************************************************************/ 253 254 public override size_t length ( ) 255 { 256 return this.clients.bucket_info.length; 257 } 258 259 /*************************************************************************** 260 261 foreach operator over registered clients. 262 263 ***************************************************************************/ 264 265 public int opApply ( scope int delegate ( ref ISelectClient ) dg ) 266 { 267 int res; 268 foreach ( client; this.clients ) 269 { 270 res = dg(client); 271 if ( res ) break; 272 } 273 return res; 274 } 275 } 276