1 /* 2 * Copyright 2012 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Paweł Dziepak, pdziepak@quarnos.org 7 */ 8 #ifndef RPCSERVER_H 9 #define RPCSERVER_H 10 11 12 #include <condition_variable.h> 13 #include <lock.h> 14 15 #include "Connection.h" 16 #include "RPCCall.h" 17 #include "RPCReply.h" 18 19 20 namespace RPC { 21 22 struct Request { 23 uint32 fXID; 24 ConditionVariable fEvent; 25 26 bool fDone; 27 Reply** fReply; 28 status_t fError; 29 30 Request* fNext; 31 }; 32 33 class RequestManager { 34 public: 35 RequestManager(); 36 ~RequestManager(); 37 38 void AddRequest(Request* req); 39 Request* FindRequest(uint32 xid); 40 41 private: 42 mutex fLock; 43 Request* fQueueHead; 44 Request* fQueueTail; 45 46 }; 47 48 class ProgramData { 49 public: 50 virtual ~ProgramData() { } 51 }; 52 53 class Server { 54 public: 55 Server(Connection* conn, 56 ServerAddress* addr); 57 virtual ~Server(); 58 59 status_t SendCall(Call* call, Reply** reply); 60 61 status_t SendCallAsync(Call* call, Reply** reply, 62 Request** request); 63 status_t ResendCallAsync(Call* call, Request* req); 64 inline status_t WaitCall(Request* request, 65 bigtime_t time = kWaitTime); 66 inline status_t CancelCall(Request* request); 67 status_t WakeCall(Request* request); 68 69 status_t Repair(); 70 71 inline const ServerAddress& ID() const; 72 inline ServerAddress LocalID() const; 73 74 inline ProgramData* PrivateData(); 75 inline void SetPrivateData(ProgramData* priv); 76 77 private: 78 inline uint32 _GetXID(); 79 80 status_t _StartListening(); 81 82 status_t _Listener(); 83 static status_t _ListenerThreadStart(void* ptr); 84 85 thread_id fThread; 86 bool fThreadCancel; 87 status_t fThreadError; 88 89 RequestManager fRequests; 90 Connection* fConnection; 91 const ServerAddress* fAddress; 92 93 ProgramData* fPrivateData; 94 95 vint32 fXID; 96 static const bigtime_t kWaitTime = 1000000; 97 }; 98 99 100 inline status_t 101 Server::WaitCall(Request* request, bigtime_t time) 102 { 103 if (request->fDone) 104 return B_OK; 105 return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time); 106 } 107 108 109 inline status_t 110 Server::CancelCall(Request* request) 111 { 112 fRequests.FindRequest(request->fXID); 113 return B_OK; 114 } 115 116 117 inline const ServerAddress& 118 Server::ID() const 119 { 120 return *fAddress; 121 } 122 123 124 inline ServerAddress 125 Server::LocalID() const 126 { 127 ServerAddress addr; 128 memset(&addr, 0, sizeof(addr)); 129 fConnection->GetLocalID(&addr); 130 return addr; 131 } 132 133 134 inline ProgramData* 135 Server::PrivateData() 136 { 137 return fPrivateData; 138 } 139 140 141 inline void 142 Server::SetPrivateData(ProgramData* priv) 143 { 144 delete fPrivateData; 145 fPrivateData = priv; 146 } 147 148 149 struct ServerNode { 150 ServerAddress fID; 151 Server* fServer; 152 int fRefCount; 153 154 ServerNode* fLeft; 155 ServerNode* fRight; 156 }; 157 158 class ServerManager { 159 public: 160 ServerManager(); 161 ~ServerManager(); 162 163 status_t Acquire(Server** pserv, uint32 ip, uint16 port, 164 Transport proto, 165 ProgramData* (*createPriv)(Server*)); 166 void Release(Server* serv); 167 168 private: 169 170 ServerNode* _Find(const ServerAddress& id); 171 void _Delete(ServerNode* node); 172 ServerNode* _Insert(ServerNode* node); 173 174 ServerNode* fRoot; 175 mutex fLock; 176 }; 177 178 } // namespace RPC 179 180 181 #endif // RPCSERVER_H 182 183