1 /* 2 * Copyright 2012-2013 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 RPCCALLBACKSERVER_H 9 #define RPCCALLBACKSERVER_H 10 11 12 #include <util/AutoLock.h> 13 14 #include "Connection.h" 15 16 17 namespace RPC { 18 19 class Callback; 20 class Server; 21 22 struct ConnectionEntry { 23 Connection* fConnection; 24 thread_id fThread; 25 26 ConnectionEntry* fNext; 27 ConnectionEntry* fPrev; 28 }; 29 30 union CallbackSlot { 31 Callback* fCallback; 32 int32 fNext; 33 }; 34 35 class CallbackServer { 36 public: 37 CallbackServer(int networkFamily); 38 ~CallbackServer(); 39 40 static CallbackServer* Get(Server* server); 41 static void ShutdownAll(); 42 43 status_t RegisterCallback(Callback* callback); 44 status_t UnregisterCallback(Callback* callback); 45 46 inline PeerAddress LocalID(); 47 48 protected: 49 status_t StartServer(); 50 status_t StopServer(); 51 52 status_t NewConnection(Connection* connection); 53 status_t ReleaseConnection(ConnectionEntry* entry); 54 55 static status_t ListenerThreadLauncher(void* object); 56 status_t ListenerThread(); 57 58 static status_t ConnectionThreadLauncher(void* object); 59 status_t ConnectionThread(ConnectionEntry* entry); 60 61 inline Callback* GetCallback(int32 id); 62 63 private: 64 static mutex fServerCreationLock; 65 static CallbackServer* fServers[2]; 66 67 mutex fConnectionLock; 68 ConnectionEntry* fConnectionList; 69 ConnectionListener* fListener; 70 71 mutex fThreadLock; 72 thread_id fThread; 73 bool fThreadRunning; 74 75 rw_lock fArrayLock; 76 CallbackSlot* fCallbackArray; 77 uint32 fArraySize; 78 int32 fFreeSlot; 79 80 int fNetworkFamily; 81 }; 82 83 84 inline PeerAddress 85 CallbackServer::LocalID() 86 { 87 PeerAddress address; 88 89 ASSERT(fListener != NULL); 90 91 memset(&address, 0, sizeof(address)); 92 fListener->GetLocalAddress(&address); 93 return address; 94 } 95 96 97 inline Callback* 98 CallbackServer::GetCallback(int32 id) 99 { 100 ReadLocker _(fArrayLock); 101 if (id >= 0 && static_cast<uint32>(id) < fArraySize) 102 return fCallbackArray[id].fCallback; 103 return NULL; 104 } 105 106 107 } // namespace RPC 108 109 #endif // RPCCALLBACKSERVER_H 110 111