1 /* 2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <ServerInterface.h> 8 9 #include <set> 10 11 #include <Autolock.h> 12 #include <Locker.h> 13 14 #include <DataExchange.h> 15 #include <MediaDebug.h> 16 17 18 namespace BPrivate { 19 namespace media { 20 21 22 class PortPool : BLocker { 23 public: 24 PortPool(); 25 ~PortPool(); 26 27 port_id GetPort(); 28 void PutPort(port_id port); 29 30 private: 31 typedef std::set<port_id> PortSet; 32 33 PortSet fPool; 34 }; 35 36 37 static PortPool sPortPool; 38 39 40 PortPool::PortPool() 41 : 42 BLocker("port pool") 43 { 44 } 45 46 47 PortPool::~PortPool() 48 { 49 PortSet::iterator iterator = fPool.begin(); 50 51 for (; iterator != fPool.end(); iterator++) 52 delete_port(*iterator); 53 } 54 55 56 port_id 57 PortPool::GetPort() 58 { 59 BAutolock _(this); 60 61 if (fPool.empty()) 62 return create_port(1, "media reply port"); 63 64 port_id port = *fPool.begin(); 65 fPool.erase(port); 66 67 ASSERT(port >= 0); 68 return port; 69 } 70 71 72 void 73 PortPool::PutPort(port_id port) 74 { 75 ASSERT(port >= 0); 76 77 BAutolock _(this); 78 79 try { 80 fPool.insert(port); 81 } catch (std::bad_alloc& exception) { 82 delete_port(port); 83 } 84 } 85 86 87 // #pragma mark - 88 89 90 request_data::request_data() 91 { 92 reply_port = sPortPool.GetPort(); 93 } 94 95 96 request_data::~request_data() 97 { 98 sPortPool.PutPort(reply_port); 99 } 100 101 102 status_t 103 request_data::SendReply(status_t result, reply_data *reply, 104 size_t replySize) const 105 { 106 reply->result = result; 107 // we cheat and use the (command_data *) version of SendToPort 108 return SendToPort(reply_port, 0, reinterpret_cast<command_data *>(reply), 109 replySize); 110 } 111 112 113 } // namespace media 114 } // namespace BPrivate 115