ROOT logo
// $Id: Saturn.h 2791 2012-06-23 01:18:47Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

#ifndef GledCore_Saturn_H
#define GledCore_Saturn_H

#include <Gled/GledTypes.h>
#include <Glasses/ZGlass.h>
#include <Stones/ZMIR.h>

class ZGod;
class ZKing; class ZFireKing;
class ZSunQueen; class ZQueen; class ZFireQueen;
class SaturnInfo; class EyeInfo; class Ray; class EyeInfoVector;
class TextMessage;

#include <Gled/GMutex.h>
#include <Gled/GSelector.h>
#include <Gled/GCondition.h>
#include <Gled/GTime.h>
class Mountain;
class ZHistoManager;
class GThread;

class TServerSocket; class TSocket;
class TMessage;


class Saturn : public An_ID_Demangler
{
  friend class Gled;
  friend class ZKing;
  friend class ZQueen; friend class ZSunQueen;
  friend class SaturnInfo;

  typedef list<SaturnInfo*>           lpSaturnInfo_t;
  typedef list<SaturnInfo*>::iterator lpSaturnInfo_i;
  typedef list<EyeInfo*>              lpEyeInfo_t;
  typedef list<EyeInfo*>::iterator    lpEyeInfo_i;

  typedef list<TSocket*>              lpSocket_t;
  typedef list<TSocket*>::iterator    lpSocket_i;

public:
  struct SocketInfo
  {
    enum OtherSide_e { OS_Moon, OS_Eye };  // What on other side ...
    OtherSide_e	fWhat;
    ZGlass*	fLensRep;

    SaturnInfo* get_moon() { return (SaturnInfo*)fLensRep; }
    EyeInfo*	get_eye()  { return (EyeInfo*)fLensRep; }

    SocketInfo(OtherSide_e w, ZGlass* g) : fWhat(w), fLensRep(g) {}
  };

#ifndef __CINT__
  typedef hash_map<TSocket*, SocketInfo>	   hSock2SocketInfo_t;
  typedef hash_map<TSocket*, SocketInfo>::iterator hSock2SocketInfo_i;
#endif

  typedef multimap<GTime, ZMIR*>           mTime2MIR_t;
  typedef multimap<GTime, ZMIR*>::iterator mTime2MIR_i;

protected:
  GMutex		mIDLock;	// X{r} ... must allow locking to eyez
  GMutex		mEyeLock;	// sending to eyes
  GMutex		mMoonLock;	// sending to moons
  GMutex		mMasterLock;	// sending to master
  GMutex		mRulingLock;	// Exec in kings & queens

  GSelector		mSelector;	// fd select wrapper for sockets

  ZGod*			mGod;		// X{g}
  ZKing*		mSunKing;	// X{g}
  ZSunQueen*		mSunQueen;	// X{g}
  ZKing*		mKing;		// X{g}
  ZFireKing*		mFireKing;	// X{g}
  ZFireQueen*		mFireQueen;	// X{g}
  SaturnInfo*		mSunInfo;	// X{g}
  SaturnInfo*		mSaturnInfo;	// X{g}
  bool			bSunAbsolute;	// X{g}

  Int_t			mQueenLoadNum;	// X{gS}
  GCondition		mQueenLoadCnd;	// X{r}

  Mountain*		mChaItOss;	// X{g}
#ifndef __CINT__
  hID2pZGlass_t		mIDHash;
  hSock2SocketInfo_t	mSock2InfoHash;
#endif
  lpSaturnInfo_t	mMoons;
  lpEyeInfo_t		mEyes;
  TServerSocket*	mServerSocket;

  // Server Thread
  GThread*		mServerThread;
  GThread*              mShutdownThread;

  Bool_t		bAllowMoons;	// X{g}


  // Detached lens threads

#ifndef __CINT__

  struct DetachedThreadInfo
  {
    ZGlass  *fLens;
    GThread *fThread;

    DetachedThreadInfo() : fLens(0), fThread(0) {}
    DetachedThreadInfo(ZGlass *l, GThread *t) : fLens(l), fThread(t) {}
  };

  typedef list<DetachedThreadInfo>           lDetachedThreadInfo_t;
  typedef list<DetachedThreadInfo>::iterator lDetachedThreadInfo_i;

  class DetachedThreadsPerLens
  {
    struct Thread
    {
      GThread               *fThread;
      lDetachedThreadInfo_i  fMainIter;

      Thread(GThread* t, lDetachedThreadInfo_i i) : fThread(t), fMainIter(i) {}
    };
    list<Thread> fThreads;
  public:
    DetachedThreadsPerLens() {}

    bool                  IsEmpty() const;
    GThread*              GetLastThread() const;
    void                  PushBack(GThread* t, lDetachedThreadInfo_i i);
    lDetachedThreadInfo_i PopBack();
    lDetachedThreadInfo_i FindAndRemove(GThread* t);
  };

  typedef hash_map<ZGlass*, DetachedThreadsPerLens>           hpZGlass2DetachedThreadPerLens_t;
  typedef hash_map<ZGlass*, DetachedThreadsPerLens>::iterator hpZGlass2DetachedThreadPerLens_i;

  lDetachedThreadInfo_t             mDetachedThreadsList;
  hpZGlass2DetachedThreadPerLens_t  mDetachedThreadsHash;
  GMutex                            mDetachedMirMutex;

public:
  void register_detached_thread  (ZGlass *lens, GThread *thread);
  void unregister_detached_thread(ZGlass *lens, GThread *thread);
protected:
  bool cancel_and_join_thread    (ZGlass* lens, GThread* thread);

#endif

  // Saturn services ... preliminary
  ZHistoManager*	pZHistoManager;

  static int start_threads(Saturn *saturn);
  int  create_server_socket();
  int  start_server();
  int  stop_server();
  int  start_shooters();
  int  stop_shooters();

  int  stop_detached_threads();

  void socket_closed(TSocket* sock);
  void wipe_moon(SaturnInfo* moon, bool notify_sunqueen_p);
  void wipe_eye(EyeInfo* eye, bool notify_sunqueen_p);

  void fix_fire_king_id(SaturnInfo* si);
  void create_kings(const char* king, const char* whore_king);
  void arrival_of_kings(TMessage* m);

  void Enlight(ZGlass* glass, ID_t) throw(Exc_t);
  void Reflect(ZGlass* glass) throw(Exc_t);
  void Freeze(ZGlass* glass) throw(Exc_t);
  void Endark(ZGlass* glass) throw(Exc_t);

  Bool_t IsMoon(SaturnInfo* si);
  void   CopyMoons(lpSaturnInfo_t& list);

  Int_t	SockSuck();	// Called constantly from ServerThread
  SaturnInfo* FindRouteTo(SaturnInfo* target);

  void AcceptWrapper(TSocket* newsocket);
  void Accept(TSocket* newsocket) throw(Exc_t);
  void finalize_moon_connection(SaturnInfo* si);
  void finalize_eye_connection(EyeInfo* ei);

  Int_t	Manage(TSocket* sock) throw(Exc_t);

public:
  Saturn();
  virtual ~Saturn();

  static TString   HandleClientSideSaturnHandshake(TSocket*& socket);
  static TMessage* HandleClientSideMeeConnection(TSocket* socket, ZMirEmittingEntity* mee);

  void	      Create(SaturnInfo* si);
  SaturnInfo* Connect(SaturnInfo* si);
  TSocket*    MakeSocketPairAndAccept(const TString& name);
  void        OpenServerSocket();
  void	      AllowMoons();
  void	      Shutdown();

  void        LockMIRShooters(bool wait_until_queue_empty=false);
  void        UnlockMIRShooters();

  virtual ZGlass* DemangleID(ID_t id);

  Int_t Freeze();
  Int_t UnFreeze();

  // Saturn services
  ZHistoManager* GetZHistoManager();

  static const Int_t s_Gled_Protocol_Version;

  /**************************************************************************/
  // MIR and MIR Result Request handling
  /**************************************************************************/

protected:

  // MIR Result Request registration and storage
  struct mir_rr_info
  {
    GCondition*  cond;
    ZMIR_RR*     mir_rr;
    mir_rr_info(GCondition* c) : cond(c), mir_rr(0) {}
  };

#ifndef __CINT__
  typedef hash_map<UInt_t, mir_rr_info>			hReqHandle2MirRRInfo_t;
  typedef hash_map<UInt_t, mir_rr_info>::iterator	hReqHandle2MirRRInfo_i;

  hReqHandle2MirRRInfo_t 	mBeamReqHandles;
#endif

  GMutex		mBeamReqHandleMutex;
  UInt_t		mLastBeamReqHandle;

  UInt_t    register_mir_result_request(GCondition* cond);
  ZMIR_RR*  query_mir_result(UInt_t req_handle);
  void	    handle_mir_result(UInt_t req_handle, ZMIR* mirp);

  GThread*		mMIRShootingThread;
  GCondition		mMIRShootingCnd;
  GMutex		mMIRShooterRoutingLock;
  list<ZMIR*>		mMIRShootingQueue;

  GThread*		mDelayedMIRShootingThread;
  GCondition		mDelayedMIRShootingCnd;
  mTime2MIR_t		mDelayedMIRShootingQueue;

  void     markup_posted_mir(ZMIR& mir, ZMirEmittingEntity* caller=0);
  void     post_mir(auto_ptr<ZMIR>& mir, ZMirEmittingEntity* caller=0);
  void     shoot_mir(auto_ptr<ZMIR>& mir, ZMirEmittingEntity* caller,
		     bool use_own_thread=false);
  void     delayed_shoot_mir(auto_ptr<ZMIR>& mir, ZMirEmittingEntity* caller,
			     GTime at_time);

  void     mir_shooter();
  void     delayed_mir_shooter();

  void     generick_shoot_mir_result(ZMIR& mir, const Text_t* exc, TBuffer* buf);

public:

  void     PostMIR(auto_ptr<ZMIR>& mir);
  void     PostMIR(ZMIR* mir);

  void     ShootMIR(auto_ptr<ZMIR>& mir, bool use_own_thread=false);
  void     ShootMIR(ZMIR* mir, bool use_own_thread=false);
  void     DelayedShootMIR(auto_ptr<ZMIR>& mir, GTime at_time);
  void     DelayedShootMIR(ZMIR* mir, GTime at_time);
  ZMIR_RR* ShootMIRWaitResult(auto_ptr<ZMIR>& mir, bool use_own_thread=false);
  ZMIR_RR* ShootMIRWaitResult(ZMIR* mir, bool use_own_thread=false);

  void     ShootMIRResult(TBuffer& buf);

  // Internal MIR handling

protected:
  void report_mir_pre_demangling_error(ZMIR& mir, TString error);
  void report_mir_post_demangling_error(ZMIR& mir, TString error);

  void RouteMIR(auto_ptr<ZMIR>& mir)  throw();
  void UnfoldMIR(auto_ptr<ZMIR>& mir) throw();
  void ExecMIR(ZMIR* mir, bool lockp=true);
  void ExecMIR(auto_ptr<ZMIR>& mir, bool lockp=true);
  void ExecDetachedMIR(auto_ptr<ZMIR>& mir);

  void ForwardMIR(ZMIR& mir, SaturnInfo* route);
  void BroadcastMIR(ZMIR& mir, lpSaturnInfo_t& moons);
  void BroadcastBeamMIR(ZMIR& mir, lpSaturnInfo_t& moons);


  /**************************************************************************/
  // Ray handling ... viewer notifications.
  /**************************************************************************/

 protected:
  typedef pair<Ray*, EyeInfoVector*> RayQueueEntry_t;
  typedef list<RayQueueEntry_t>      RayQueue_t;

  Bool_t                bAcceptsRays;

  GThread*              mRayEmittingThread;
  GCondition            mRayEmittingCnd;
  RayQueue_t            mRayEmittingQueue;

  void ray_emitter();

 public:

  Bool_t AcceptsRays() const { return bAcceptsRays; }

  void   Shine(auto_ptr<Ray>& ray, EyeInfoVector* eiv);

  /**************************************************************************/
  // Internal thread structures and functions
  /**************************************************************************/

private:

  // ThreadInfo structures (passed via void* to threads)

  struct new_connection_ti
  {
    Saturn*		sat;
    TSocket*		sock;
    new_connection_ti(Saturn* s, TSocket* so) : sat(s), sock(so) {}
  };

  // Thread functions

  static void* tl_SaturnFdSucker(Saturn *s);
  static void* tl_SaturnAcceptor(new_connection_ti *ss);
  static void* tl_MIR_Router(Saturn* sat);
  static void* tl_MIR_DetachedExecutor(Saturn* sat);
  static void  tl_MIR_DetachedCleanUp(Saturn* sat);

  static void* tl_MIR_Shooter(Saturn* s);
  static void* tl_Delayed_MIR_Shooter(Saturn* s);
  static void* tl_Ray_Emitter(Saturn* s);

public:
#include "Saturn.h7"
  ClassDef(Saturn, 0);
}; // endclass Saturn

/**************************************************************************/

#ifndef __CINT__

inline ZGlass* Saturn::DemangleID(ID_t id)
{
  mIDLock.Lock();
  hID2pZGlass_i i = mIDHash.find(id);
  ZGlass *ret = (i != mIDHash.end()) ? i->second : 0;
  mIDLock.Unlock();
  return ret;
}

#endif

/**************************************************************************/

#endif
 Saturn.h:1
 Saturn.h:2
 Saturn.h:3
 Saturn.h:4
 Saturn.h:5
 Saturn.h:6
 Saturn.h:7
 Saturn.h:8
 Saturn.h:9
 Saturn.h:10
 Saturn.h:11
 Saturn.h:12
 Saturn.h:13
 Saturn.h:14
 Saturn.h:15
 Saturn.h:16
 Saturn.h:17
 Saturn.h:18
 Saturn.h:19
 Saturn.h:20
 Saturn.h:21
 Saturn.h:22
 Saturn.h:23
 Saturn.h:24
 Saturn.h:25
 Saturn.h:26
 Saturn.h:27
 Saturn.h:28
 Saturn.h:29
 Saturn.h:30
 Saturn.h:31
 Saturn.h:32
 Saturn.h:33
 Saturn.h:34
 Saturn.h:35
 Saturn.h:36
 Saturn.h:37
 Saturn.h:38
 Saturn.h:39
 Saturn.h:40
 Saturn.h:41
 Saturn.h:42
 Saturn.h:43
 Saturn.h:44
 Saturn.h:45
 Saturn.h:46
 Saturn.h:47
 Saturn.h:48
 Saturn.h:49
 Saturn.h:50
 Saturn.h:51
 Saturn.h:52
 Saturn.h:53
 Saturn.h:54
 Saturn.h:55
 Saturn.h:56
 Saturn.h:57
 Saturn.h:58
 Saturn.h:59
 Saturn.h:60
 Saturn.h:61
 Saturn.h:62
 Saturn.h:63
 Saturn.h:64
 Saturn.h:65
 Saturn.h:66
 Saturn.h:67
 Saturn.h:68
 Saturn.h:69
 Saturn.h:70
 Saturn.h:71
 Saturn.h:72
 Saturn.h:73
 Saturn.h:74
 Saturn.h:75
 Saturn.h:76
 Saturn.h:77
 Saturn.h:78
 Saturn.h:79
 Saturn.h:80
 Saturn.h:81
 Saturn.h:82
 Saturn.h:83
 Saturn.h:84
 Saturn.h:85
 Saturn.h:86
 Saturn.h:87
 Saturn.h:88
 Saturn.h:89
 Saturn.h:90
 Saturn.h:91
 Saturn.h:92
 Saturn.h:93
 Saturn.h:94
 Saturn.h:95
 Saturn.h:96
 Saturn.h:97
 Saturn.h:98
 Saturn.h:99
 Saturn.h:100
 Saturn.h:101
 Saturn.h:102
 Saturn.h:103
 Saturn.h:104
 Saturn.h:105
 Saturn.h:106
 Saturn.h:107
 Saturn.h:108
 Saturn.h:109
 Saturn.h:110
 Saturn.h:111
 Saturn.h:112
 Saturn.h:113
 Saturn.h:114
 Saturn.h:115
 Saturn.h:116
 Saturn.h:117
 Saturn.h:118
 Saturn.h:119
 Saturn.h:120
 Saturn.h:121
 Saturn.h:122
 Saturn.h:123
 Saturn.h:124
 Saturn.h:125
 Saturn.h:126
 Saturn.h:127
 Saturn.h:128
 Saturn.h:129
 Saturn.h:130
 Saturn.h:131
 Saturn.h:132
 Saturn.h:133
 Saturn.h:134
 Saturn.h:135
 Saturn.h:136
 Saturn.h:137
 Saturn.h:138
 Saturn.h:139
 Saturn.h:140
 Saturn.h:141
 Saturn.h:142
 Saturn.h:143
 Saturn.h:144
 Saturn.h:145
 Saturn.h:146
 Saturn.h:147
 Saturn.h:148
 Saturn.h:149
 Saturn.h:150
 Saturn.h:151
 Saturn.h:152
 Saturn.h:153
 Saturn.h:154
 Saturn.h:155
 Saturn.h:156
 Saturn.h:157
 Saturn.h:158
 Saturn.h:159
 Saturn.h:160
 Saturn.h:161
 Saturn.h:162
 Saturn.h:163
 Saturn.h:164
 Saturn.h:165
 Saturn.h:166
 Saturn.h:167
 Saturn.h:168
 Saturn.h:169
 Saturn.h:170
 Saturn.h:171
 Saturn.h:172
 Saturn.h:173
 Saturn.h:174
 Saturn.h:175
 Saturn.h:176
 Saturn.h:177
 Saturn.h:178
 Saturn.h:179
 Saturn.h:180
 Saturn.h:181
 Saturn.h:182
 Saturn.h:183
 Saturn.h:184
 Saturn.h:185
 Saturn.h:186
 Saturn.h:187
 Saturn.h:188
 Saturn.h:189
 Saturn.h:190
 Saturn.h:191
 Saturn.h:192
 Saturn.h:193
 Saturn.h:194
 Saturn.h:195
 Saturn.h:196
 Saturn.h:197
 Saturn.h:198
 Saturn.h:199
 Saturn.h:200
 Saturn.h:201
 Saturn.h:202
 Saturn.h:203
 Saturn.h:204
 Saturn.h:205
 Saturn.h:206
 Saturn.h:207
 Saturn.h:208
 Saturn.h:209
 Saturn.h:210
 Saturn.h:211
 Saturn.h:212
 Saturn.h:213
 Saturn.h:214
 Saturn.h:215
 Saturn.h:216
 Saturn.h:217
 Saturn.h:218
 Saturn.h:219
 Saturn.h:220
 Saturn.h:221
 Saturn.h:222
 Saturn.h:223
 Saturn.h:224
 Saturn.h:225
 Saturn.h:226
 Saturn.h:227
 Saturn.h:228
 Saturn.h:229
 Saturn.h:230
 Saturn.h:231
 Saturn.h:232
 Saturn.h:233
 Saturn.h:234
 Saturn.h:235
 Saturn.h:236
 Saturn.h:237
 Saturn.h:238
 Saturn.h:239
 Saturn.h:240
 Saturn.h:241
 Saturn.h:242
 Saturn.h:243
 Saturn.h:244
 Saturn.h:245
 Saturn.h:246
 Saturn.h:247
 Saturn.h:248
 Saturn.h:249
 Saturn.h:250
 Saturn.h:251
 Saturn.h:252
 Saturn.h:253
 Saturn.h:254
 Saturn.h:255
 Saturn.h:256
 Saturn.h:257
 Saturn.h:258
 Saturn.h:259
 Saturn.h:260
 Saturn.h:261
 Saturn.h:262
 Saturn.h:263
 Saturn.h:264
 Saturn.h:265
 Saturn.h:266
 Saturn.h:267
 Saturn.h:268
 Saturn.h:269
 Saturn.h:270
 Saturn.h:271
 Saturn.h:272
 Saturn.h:273
 Saturn.h:274
 Saturn.h:275
 Saturn.h:276
 Saturn.h:277
 Saturn.h:278
 Saturn.h:279
 Saturn.h:280
 Saturn.h:281
 Saturn.h:282
 Saturn.h:283
 Saturn.h:284
 Saturn.h:285
 Saturn.h:286
 Saturn.h:287
 Saturn.h:288
 Saturn.h:289
 Saturn.h:290
 Saturn.h:291
 Saturn.h:292
 Saturn.h:293
 Saturn.h:294
 Saturn.h:295
 Saturn.h:296
 Saturn.h:297
 Saturn.h:298
 Saturn.h:299
 Saturn.h:300
 Saturn.h:301
 Saturn.h:302
 Saturn.h:303
 Saturn.h:304
 Saturn.h:305
 Saturn.h:306
 Saturn.h:307
 Saturn.h:308
 Saturn.h:309
 Saturn.h:310
 Saturn.h:311
 Saturn.h:312
 Saturn.h:313
 Saturn.h:314
 Saturn.h:315
 Saturn.h:316
 Saturn.h:317
 Saturn.h:318
 Saturn.h:319
 Saturn.h:320
 Saturn.h:321
 Saturn.h:322
 Saturn.h:323
 Saturn.h:324
 Saturn.h:325
 Saturn.h:326
 Saturn.h:327
 Saturn.h:328
 Saturn.h:329
 Saturn.h:330
 Saturn.h:331
 Saturn.h:332
 Saturn.h:333
 Saturn.h:334
 Saturn.h:335
 Saturn.h:336
 Saturn.h:337
 Saturn.h:338
 Saturn.h:339
 Saturn.h:340
 Saturn.h:341
 Saturn.h:342
 Saturn.h:343
 Saturn.h:344
 Saturn.h:345
 Saturn.h:346
 Saturn.h:347
 Saturn.h:348
 Saturn.h:349
 Saturn.h:350
 Saturn.h:351
 Saturn.h:352
 Saturn.h:353
 Saturn.h:354
 Saturn.h:355
 Saturn.h:356
 Saturn.h:357
 Saturn.h:358
 Saturn.h:359
 Saturn.h:360
 Saturn.h:361
 Saturn.h:362
 Saturn.h:363
 Saturn.h:364
 Saturn.h:365
 Saturn.h:366
 Saturn.h:367
 Saturn.h:368
 Saturn.h:369
 Saturn.h:370
 Saturn.h:371
 Saturn.h:372
 Saturn.h:373