00001 /******************************************************************************* 00002 00003 @file ServerThread.d 00004 00005 Copyright (C) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 00027 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00028 00029 00030 @version Initial version, April 2004 00031 @author Kris 00032 00033 00034 *******************************************************************************/ 00035 00036 module mango.utils.ServerThread; 00037 00038 private import std.thread; 00039 00040 private import mango.io.Conduit, 00041 mango.io.Exception, 00042 mango.io.ServerSocket, 00043 mango.io.SocketConduit; 00044 00045 private import mango.utils.AbstractServer; 00046 00047 /****************************************************************************** 00048 00049 Subclasses Thread to provide the basic server-thread loop. This 00050 functionality could also be implemented as a delegate, however, 00051 we also wish to subclass in order to add thread-local data (see 00052 HttpThread). 00053 00054 ******************************************************************************/ 00055 00056 class ServerThread : Thread 00057 { 00058 ServerSocket socket; 00059 AbstractServer server; 00060 00061 /********************************************************************** 00062 00063 Construct a ServerThread for the given Server, upon the 00064 specified socket 00065 00066 **********************************************************************/ 00067 00068 this (AbstractServer server, ServerSocket socket) 00069 { 00070 this.server = server; 00071 this.socket = socket; 00072 } 00073 00074 /********************************************************************** 00075 00076 Execute this thread until the Server says to halt. Each 00077 thread waits in the socket.accept() state, waiting for 00078 a connection request to arrive. Upon selection, a thread 00079 dispatches the request via the request service-handler 00080 and, upon completion, enters the socket.accept() state 00081 once more. 00082 00083 **********************************************************************/ 00084 00085 override int run() 00086 { 00087 while (true) 00088 try { 00089 // should we bail out? 00090 if (Socket.isCancelled) 00091 return 0; 00092 00093 // wait for a socket connection 00094 SocketConduit sc = socket.accept (); 00095 00096 // did we get a valid response? 00097 if (sc) 00098 // yep: process this request 00099 server.service (this, sc); 00100 else 00101 // server may be halting ... 00102 if (! Socket.isCancelled) 00103 server.getLogger.error ("Socket accept() failed"); 00104 00105 } catch (IOException x) 00106 { 00107 server.getLogger.error ("IOException: "~x.toString); 00108 } 00109 catch (Object x) 00110 { 00111 server.getLogger.fatal ("Exception: "~x.toString); 00112 } 00113 } 00114 }