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