1 jls.loader.provide('jls.net.SelectorThread');
  2 
  3 jls.loader.requireLibrary('jls_net');
  4 jls.loader.require('jls.lang.Thread');
  5 jls.loader.require('jls.net.Selector');
  6 jls.loader.require('jls.net.PollableEvent');
  7 
  8 jls.net.SelectorThread = jls.lang.Class.create( /** @lends jls.net.SelectorThread.prototype */
  9 {
 10     /**
 11      * Creates a selector thread.
 12      *
 13      * @constructs
 14 	 * @class This class provides selector facilities hidding the selection by using a thread and a pollable event.
 15 	 * @see jls.net.Selector
 16 	 * @see jls.lang.Thread
 17 	 * @see jls.net.PollableEvent
 18      */
 19     initialize : function() {
 20         this._selector = new jls.net.Selector();
 21         this._event = new jls.net.PollableEvent();
 22         this._selector.register(this._event, this._event, jls.net.Selector.OP_READ);
 23         this._thread = new jls.lang.Thread();
 24         this._stopped = true;
 25     },
 26     /**
 27      * Returns the selector.
 28      * 
 29      * @returns {jls.net.Selector} The selector.
 30      */
 31     getSelector : function() {
 32         return this._selector;
 33     },
 34     /**
 35      * Starts this selector thread.
 36      * 
 37      * @returns {jls.net.SelectorThread} This selector thread.
 38      */
 39     start : function() {
 40         if (this._stopped) {
 41             this._thread.run = this.run;
 42             this._stopped = false;
 43             this._thread.start(this);
 44         }
 45         return this;
 46     },
 47     /**
 48      * Stops this selector thread.
 49      * 
 50      * @returns {jls.net.SelectorThread} This selector thread.
 51      */
 52     stop : function() {
 53         if (! this._stopped) {
 54             this._stopped = true;
 55             this._event.set();
 56         }
 57         return this;
 58     },
 59     /**
 60      * Registers a socket in this selector thread.
 61      * 
 62      * @param {jls.net.Socket} socket The socket to register.
 63      * @param {Function} handle The handle for this registration.
 64      * @param {Number} [mode] The interest set for this registration.
 65      * @returns {Object} The selection key.
 66      */
 67     register : function(socket, handle, mode) {
 68         var key = this.lazyregister(socket, handle, mode);
 69         if (! this._stopped) {
 70             this._event.set();
 71         }
 72         return key;
 73     },
 74     lazyregister : function(socket, handle, mode) {
 75         var key = {
 76             selectorThread: this,
 77             handle: handle,
 78             socket: socket
 79         };
 80         mode = mode || _native.net.POLL_READ;
 81         this._selector.register(socket, key, mode);
 82         return key;
 83     },
 84     /**
 85      * Removes a socket from this selector thread.
 86      * 
 87      * @param {Object} key The selection key.
 88      * @returns {jls.net.SelectorThread} This selector thread.
 89      */
 90     unregister : function(key) {
 91         this.lazyunregister(key);
 92         if (! this._stopped) {
 93             this._event.set();
 94         }
 95         return this;
 96     },
 97     lazyunregister : function(key) {
 98         this._selector.unregister(key);
 99         return this;
100     },
101     changeMode : function(key, mode) {
102         return this._selector.register(key.socket, key, mode);
103     },
104     changeHandler : function(key, handle) {
105         var oldHandle = key.handle;
106         key.handle = handle;
107         return oldHandle;
108     },
109     run : function() {
110         jls.logger.debug('SelectorThread started');
111         while (! this._stopped) {
112             var keys = this._selector.select();
113             jls.logger.debug(keys.length + ' key(s) selected');
114             //jls.lang.Thread.sleep(1000);
115             for (var i = 0; i < keys.length;  i++) {
116                 var sk = keys[i];
117                 if ('handle' in sk.key) {
118                     jls.logger.debug('handle...');
119                     sk.key.handle(sk.key, sk.inFlags, sk.outFlags);
120                 } else if (sk.key instanceof jls.net.PollableEvent) {
121                     jls.logger.debug('pollable event received');
122                     sk.key.wait();
123                 } else {
124                     jls.logger.debug('unknown event received');
125                 }
126             }
127         }
128         
129     }
130 });
131