Main Page | Class Hierarchy | Class List | File List | Class Members

main.h

00001 /*
00002  * main.h
00003  *
00004  * PWLib application header file for server
00005  *
00006  * The contents of this file are subject to the Mozilla Public License
00007  * Version 1.0 (the "License"); you may not use this file except in
00008  * compliance with the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS"
00012  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00013  * the License for the specific language governing rights and limitations
00014  * under the License.
00015  *
00016  * Copyright (c) 2006 Indranet Technologies Ltd
00017  *
00018  * The Original Code is Sofa Switch
00019  *
00020  * The Initial Developer of the Original Code is Derek J Smithies
00021  *
00022  * $Log: main.h,v $
00023  * Revision 1.32  2006/05/15 04:43:38  derek
00024  * Add to debugging information. Tidy up close down procedure for non used nodes.
00025  *
00026  * Revision 1.31  2006/05/10 04:08:23  derek
00027  * Add status full command, and the ability to track the number of created
00028  * TcpConnection classes
00029  *
00030  * Revision 1.30  2006/05/09 03:10:12  derek
00031  * More fixes, so as to cope with lots of concurrent messages.
00032  *
00033  * Revision 1.29  2006/05/09 02:11:24  derek
00034  * add multiple fixes, so it correctly handles empty messages, and correctly terminates.
00035  *
00036  * Revision 1.28  2006/04/24 03:47:08  derek
00037  * Updates to get the server to work correctly, and compile issues for jopal
00038  *
00039  * Revision 1.27  2006/03/31 04:44:00  derek
00040  * Modifications, to ensure all is deleted and closed down corectly.
00041  *
00042  * Revision 1.26  2006/03/23 08:19:12  derek
00043  * Fix threading issues for SMP machines.
00044  *
00045  * Revision 1.25  2006/03/22 01:30:48  derek
00046  * Add logging statements for error type things, and reduce the number of
00047  * memory allocations to handle each message.
00048  * Make use of const in passing parameters.
00049  *
00050  * Revision 1.24  2006/03/21 01:33:46  derek
00051  * tidyups tidyups, fix licenses, fix makefiles,
00052  *
00053  * Revision 1.23  2006/03/16 01:59:03  derek
00054  * Remove audio read write thread pointers from the am.
00055  * tidy up the handling of the remoteController name in the MessageFrame class.
00056  * Extend the python control scripts to be a bit tougher.
00057  *
00058  * Revision 1.22  2006/03/10 02:43:10  derek
00059  * add flag to report when messages are sent to the remote node.
00060  * Tidyup the displayed code.
00061  * Adjust the time that the output mutex is locked.
00062  *
00063  * Revision 1.21  2006/01/23 07:28:55  derek
00064  * Modify some print statements,
00065  *
00066  * Revision 1.20  2006/01/23 04:09:51  derek
00067  * Add reporting function.
00068  *
00069  * Revision 1.19  2006/01/18 03:57:52  derek
00070  * Minor tidyups to chase a memory management bug. Proves to be in the glibc of
00071  * the Fedora Core 1 testbox.
00072  *
00073  * Revision 1.18  2006/01/12 22:56:53  derek
00074  * Tidy up documentation. Use a pointer in local storage for the manager.
00075  *
00076  * Revision 1.17  2006/01/12 04:12:48  derek
00077  * Work on documentating the protocol, and rename the Server class inside main.cxx/main.h
00078  *
00079  * Revision 1.16  2006/01/09 04:23:38  derek
00080  * Move Resume() out of constructor for any class. Resuming within a constructor is bad,
00081  * as it creates a thread before the class is finished building.
00082  *
00083  * Revision 1.15  2005/12/14 04:07:36  derek
00084  * Add a thread & list to prebuild comms before they are needed, to speed the call setup process.
00085  * It is also allows us to cope better with the times when Comms setup fails.
00086  *
00087  * Revision 1.14  2005/12/12 00:25:42  derek
00088  * Fix the close down etc process of dead TcpConnections. Excise memory leaks.
00089  *
00090  * Revision 1.13  2005/12/07 00:44:13  derek
00091  * given results from the program to test the server, get the messaging code
00092  * to attempt to reconnect to the server. Modify server to have
00093  * prebuilt, ready to go TcpConnections which do an accept after receiving
00094  * a request to the server's listen
00095  *
00096  * Revision 1.12  2005/12/05 04:07:05  derek
00097  * Modify server to end more cleanly.
00098  * Work on adding additional debugging messages.
00099  * Move work out of the constructors.
00100  *
00101  * Revision 1.11  2005/12/01 02:25:49  derek
00102  * update server to exit cleanly.
00103  *
00104  * Revision 1.10  2005/11/29 23:26:42  derek
00105  * put keep alives and code to detect the death of the connection.
00106  *
00107  * Revision 1.9  2005/11/17 23:17:52  derek
00108  * Add a short lived thread to actually delete TcpConnection class, rather than
00109  * trying to do it elsewhere.
00110  *
00111  * Revision 1.8  2005/11/13 23:52:26  derek
00112  * Work on documentation.
00113  *
00114  * Revision 1.7  2005/11/08 23:20:08  derek
00115  * Fix close down process for C++ code.
00116  * Add "list" option, so remote node can see who is on.
00117  *
00118  * Revision 1.6  2005/11/07 23:11:54  derek
00119  * Add ability to close the server by sending the message "quitnow"
00120  *
00121  * Revision 1.5  2005/11/07 04:06:08  derek
00122  * Add a null byte to the end of the id, which ensures the id is not merged
00123  * into the next message by the network stack.
00124  *
00125  * Revision 1.4  2005/11/06 21:29:49  derek
00126  * Add null bytes to the end of each message sent.
00127  *
00128  * Revision 1.3  2005/11/04 04:00:32  derek
00129  * Add handling to cope with multiple text messages in one packet.
00130  * Each message is terminated by a 0 character.
00131  *
00132  * Revision 1.2  2005/11/04 02:43:07  derek
00133  * Add loop counting options to cause program exit.
00134  * Fix warnings about unused variables.
00135  *
00136  * Revision 1.1  2005/11/04 01:35:52  derek
00137  * Initial release of a C++ based simple messaging server
00138  *
00139  *
00140  *
00141  *
00142  *
00143  *
00144  */
00145  
00146 #ifndef _MAIN_H
00147 #define _MAIN_H
00148 
00149 #pragma interface
00150 
00151 #include <ptlib.h>
00152 #include <ptlib/sockets.h>
00153 #include <ptlib/safecoll.h>
00154 
00155 
00156 
00157 class TcpConnectionList;
00158 class TcpConnection;
00159 class Manager;
00160 
00162 
00164 class TcpConnection : public PSafeObject
00165 {
00166   PCLASSINFO(TcpConnection, PSafeObject);
00167  public:
00169   TcpConnection(Manager & _mgr);
00170   
00172   ~TcpConnection();
00173 
00175   void StartRunning();
00176 
00178   BOOL IsRunning();
00179 
00181   void PrintOn(ostream & strm) const;
00182 
00184   void Terminate();
00185 
00189   void AssignSourceId(PString & newId) { sourceId = newId; }
00190 
00192   PString GetSourceId() { return sourceId; }
00193 
00195   void Clear();
00196 
00198   void StartWorkNow(PTCPSocket &listener);
00199 
00202   void StartWorkNowNotPossible();
00203 
00204  protected:
00205 
00207   PString GetNow();
00208 
00213   void DoOneMessage();
00214 
00218   void BreakUpMessageBlock(PBYTEArray & src, PINDEX srcLen, PStringArray & result);
00219 
00222   void ProcessOneTextMessage(const PString & txt);
00223   
00225   void SendThisMessage(PBYTEArray & msg);
00226 
00228   Manager & manager;    
00229 
00230 #ifdef DOC_PLUS_PLUS
00231 
00234     virtual void OnReleaseThreadMain(PThread &, INT);
00235 #else
00236     PDECLARE_NOTIFIER(PThread, TcpConnection, OnReleaseThreadMain);
00237 #endif
00238 
00245     virtual void OnReleased();
00246     
00248     PMutex writeMessageLock;
00249     
00251     PMutex   incomingLock;
00252     
00255     PThread  *incomingMessages;
00256     
00257 #ifdef DOC_PLUS_PLUS
00258 
00259     virtual void IncomingMessagesMain(PThread &, INT);
00260 #else
00261     PDECLARE_NOTIFIER(PThread, TcpConnection, IncomingMessagesMain);
00262 #endif
00263     
00265   PSyncPoint socketInitialised;
00266   
00269   PTCPSocket messagesSocket;
00270   
00272   PString sourceId;  
00273 
00275   enum {
00276     readArraySize = 10  
00277   };
00278 
00280   PINDEX readArray[readArraySize];
00281 
00283   PINDEX readArrayIndex;
00284 
00286   PMutex clearMutex;
00287 
00289   BOOL isClearing;
00290 
00292   BOOL reportReadMessages;
00293 
00298   BOOL reportSentMessages;
00299 
00303   PBYTEArray message;
00304 
00307   PString thisThreadName;
00308 
00310   PString clearName;
00311 
00315   PString globalUniqueId;
00316 };
00317 
00319 
00320 PDECLARE_LIST (TcpConnectionList, TcpConnection *)
00321 #ifdef DOC_PLUS_PLUS     //This makes emacs bracket matching code happy.
00329 class TcpConnectionList : public TcpConnection *
00330 {
00331 #endif
00332 
00334   ~TcpConnectionList();
00335 
00337   void CloseDown();
00338 
00340   void Initialise();
00341 
00342   #ifdef DOC_PLUS_PLUS
00343 
00345   void FillListWithTcpConnections(PThread &, INT param);
00346 #else
00347   PDECLARE_NOTIFIER(PThread, TcpConnectionList, FillListWithTcpConnections);
00348 #endif
00349 
00352   TcpConnection * GetNextTcpConnection();
00353 
00355   PINDEX GetListSize() { PWaitAndSignal m(accessMutex); return PAbstractList::GetSize(); }
00356 
00357  protected:
00359   TcpConnection *MakeOneTcpConnection();
00360 
00362   PSyncPoint checkListContents;
00363 
00365   PMutex accessMutex;
00366 
00368   PThread *createNewTcpConnections;
00369 
00371   PMutex mutexNewTcpConnections;
00372 
00374   BOOL endNow;
00375 };
00376 
00378 
00381 class Manager : public PObject
00382 {
00383   PCLASSINFO(Manager, PObject);
00384  public:
00386   Manager();
00387 
00389   ~Manager();
00390 
00394     PSafePtr<TcpConnection> GetConnectionWithLock(
00395       const PString & token     
00396       ,PSafetyMode mode = PSafeReadWrite  
00397     ) { return connectionsActive.FindWithLock(token, mode); }
00398  
00400     void RemoveNode(const PString & token);
00401 
00404     void WaitForIncoming();
00405 
00408     PString ProcessMessagesName();
00409 
00412     void AppendRunning(PSafePtr<TcpConnection> conn, const PString & id);
00413 
00418     void AppendDead(PSafePtr<TcpConnection> conn);
00419 
00421     void QuitNow();
00422 
00424     void StopIncomingConnections();
00425 
00428     void GetListConnectedNodes(PStringArray & nodes);
00429 
00431     BOOL KeepRunning() { return keepRunning; }
00432 
00435     void OnReleased(TcpConnection & connection);
00436 
00438     void WaitForEmpty();
00439 
00441     void GetStatus(PStringStream &status);
00442 
00446     PString GetNextBogusId();    
00447  protected:
00448 
00450  class ConnectionDict : public PSafeDictionary<PString, TcpConnection>
00451     {
00456         virtual void DeleteObject(PObject * object) const;
00457     } connectionsActive;
00458 
00459 #ifdef DOC_PLUS_PLUS
00460 
00462  virtual void DoQuitNow(PThread &, INT);
00463 #else
00464  PDECLARE_NOTIFIER(PThread, Manager, DoQuitNow);
00465 #endif
00466  
00468     PTCPSocket listener;
00469 
00471     PAtomicInteger bogusCount;
00472 
00474     PAtomicInteger connectionCount;
00475 
00477     TcpConnectionList availableTcpConnections;
00478 
00480     BOOL keepRunning;
00481 
00483     BOOL isQuitting;
00484 
00486     PMutex quitNowMutex;
00487 };
00488 
00490 
00493 class ServerProcess : public PProcess
00494 {
00495   PCLASSINFO(ServerProcess, PProcess);
00496 
00497 public:
00499   ServerProcess();
00500 
00502   ~ServerProcess();
00503 
00505   void Main();
00506 
00509   static ServerProcess & Current()
00510     { return (ServerProcess &)PProcess::Current(); }
00511 
00513   BOOL ReportReadMessages() { return reportReadMessages; }
00514 
00516   BOOL ReportSentMessages() { return reportSentMessages; }
00517 
00519   Manager & GetManager() { return localManager; }
00520 
00521  protected:
00522 
00524   Manager localManager;
00525 
00527   BOOL reportReadMessages;
00528 
00533   BOOL reportSentMessages;
00534 };
00536 
00537 #endif  // _MAIN_H

Generated on Thu Apr 19 00:03:11 2007 for SSServer, or Sofa Switch Server by  doxygen 1.4.4