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 "RPCCallback.h" 18 #include "RPCReply.h" 19 20 21 namespace RPC { 22 23 struct Request { 24 uint32 fXID; 25 ConditionVariable fEvent; 26 27 bool fDone; 28 Reply** fReply; 29 status_t fError; 30 31 Request* fNext; 32 }; 33 34 class RequestManager { 35 public: 36 RequestManager(); 37 ~RequestManager(); 38 39 void AddRequest(Request* request); 40 Request* FindRequest(uint32 xid); 41 42 private: 43 mutex fLock; 44 Request* fQueueHead; 45 Request* fQueueTail; 46 47 }; 48 49 class ProgramData { 50 public: 51 virtual status_t ProcessCallback(CallbackRequest* request, 52 Connection* connection) = 0; 53 54 virtual ~ProgramData() { } 55 }; 56 57 class Server { 58 public: 59 Server(Connection* connection, 60 PeerAddress* address); 61 virtual ~Server(); 62 63 status_t SendCallAsync(Call* call, Reply** reply, 64 Request** request); 65 status_t ResendCallAsync(Call* call, 66 Request* request); 67 68 inline status_t WaitCall(Request* request, 69 bigtime_t time); 70 inline status_t CancelCall(Request* request); 71 status_t WakeCall(Request* request); 72 73 status_t Repair(); 74 75 inline const PeerAddress& ID() const; 76 inline PeerAddress LocalID() const; 77 78 inline ProgramData* PrivateData(); 79 inline void SetPrivateData(ProgramData* privateData); 80 81 Callback* GetCallback(); 82 83 private: 84 inline uint32 _GetXID(); 85 86 status_t _StartListening(); 87 88 status_t _Listener(); 89 static status_t _ListenerThreadStart(void* object); 90 91 thread_id fThread; 92 bool fThreadCancel; 93 status_t fThreadError; 94 95 RequestManager fRequests; 96 Connection* fConnection; 97 const PeerAddress* fAddress; 98 99 ProgramData* fPrivateData; 100 101 mutex fCallbackLock; 102 Callback* fCallback; 103 104 uint32 fRepairCount; 105 mutex fRepairLock; 106 107 vint32 fXID; 108 }; 109 110 111 inline status_t 112 Server::WaitCall(Request* request, bigtime_t time) 113 { 114 if (request->fDone) 115 return B_OK; 116 return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time); 117 } 118 119 120 inline status_t 121 Server::CancelCall(Request* request) 122 { 123 fRequests.FindRequest(request->fXID); 124 return B_OK; 125 } 126 127 128 inline const PeerAddress& 129 Server::ID() const 130 { 131 return *fAddress; 132 } 133 134 135 inline PeerAddress 136 Server::LocalID() const 137 { 138 PeerAddress addr; 139 memset(&addr, 0, sizeof(addr)); 140 fConnection->GetLocalAddress(&addr); 141 return addr; 142 } 143 144 145 inline ProgramData* 146 Server::PrivateData() 147 { 148 return fPrivateData; 149 } 150 151 152 inline void 153 Server::SetPrivateData(ProgramData* privateData) 154 { 155 delete fPrivateData; 156 fPrivateData = privateData; 157 } 158 159 160 struct ServerNode { 161 PeerAddress fID; 162 Server* fServer; 163 int fRefCount; 164 165 ServerNode* fLeft; 166 ServerNode* fRight; 167 }; 168 169 class ServerManager { 170 public: 171 ServerManager(); 172 ~ServerManager(); 173 174 status_t Acquire(Server** _server, const PeerAddress& address, 175 ProgramData* (*createPrivateData)(Server*)); 176 void Release(Server* server); 177 178 private: 179 180 ServerNode* _Find(const PeerAddress& address); 181 void _Delete(ServerNode* node); 182 ServerNode* _Insert(ServerNode* node); 183 184 ServerNode* fRoot; 185 mutex fLock; 186 }; 187 188 } // namespace RPC 189 190 191 #endif // RPCSERVER_H 192 193