diff --git a/headers/private/media/PortPool.h b/headers/private/media/PortPool.h index 9dcca98983..eb087887d1 100644 --- a/headers/private/media/PortPool.h +++ b/headers/private/media/PortPool.h @@ -1,35 +1,41 @@ /* - * Copyright 2002, Marcus Overhagen. All Rights Reserved. + * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ -#ifndef _POOL_PORT_H_ -#define _POOL_PORT_H_ +#ifndef PORT_POOL_H +#define PORT_POOL_H -class PortPool { +#include + +#include + + +namespace BPrivate { + + +class PortPool : BLocker { public: - PortPool(); - ~PortPool(); + PortPool(); + ~PortPool(); - port_id GetPort(); - void PutPort(port_id port); + port_id GetPort(); + void PutPort(port_id port); private: - void Lock(); - void Unlock(); + typedef std::set PortSet; - struct PortInfo { - port_id port; - bool used; - }; - - PortInfo * pool; - int count; - int maxcount; - int32 locker_atom; - sem_id locker_sem; + PortSet fPool; }; -extern PortPool *_PortPool; -#endif +extern PortPool* gPortPool; + + +} // namespace BPrivate + + +using BPrivate::gPortPool; + + +#endif // PORT_POOL_H diff --git a/src/kits/media/DataExchange.cpp b/src/kits/media/DataExchange.cpp index ddb48ff041..20de13b229 100644 --- a/src/kits/media/DataExchange.cpp +++ b/src/kits/media/DataExchange.cpp @@ -179,7 +179,7 @@ QueryPort(port_id requestport, int32 msgcode, request_data *request, int request status_t rv; int32 code; - request->reply_port = _PortPool->GetPort(); + request->reply_port = gPortPool->GetPort(); rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); @@ -192,20 +192,20 @@ QueryPort(port_id requestport, int32 msgcode, request_data *request, int request find_media_addon_server_port(); requestport = MediaAddonServerPort; } else { - _PortPool->PutPort(request->reply_port); + gPortPool->PutPort(request->reply_port); return rv; } rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); if (rv != B_OK) { ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); - _PortPool->PutPort(request->reply_port); + gPortPool->PutPort(request->reply_port); return rv; } } rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT); - _PortPool->PutPort(request->reply_port); + gPortPool->PutPort(request->reply_port); if (rv < B_OK) { ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv)); diff --git a/src/kits/media/DormantNodeManager.cpp b/src/kits/media/DormantNodeManager.cpp index e624268954..c163b2548e 100644 --- a/src/kits/media/DormantNodeManager.cpp +++ b/src/kits/media/DormantNodeManager.cpp @@ -213,12 +213,12 @@ DormantNodeManager::RegisterAddOn(const char* path) return 0; } - msg.reply_port = _PortPool->GetPort(); + msg.reply_port = gPortPool->GetPort(); msg.ref = ref; status = write_port(port, SERVER_REGISTER_MEDIAADDON, &msg, sizeof(msg)); if (status != B_OK) { - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); ERROR("DormantNodeManager::RegisterAddon failed, couldn't talk to " "media server\n"); return 0; @@ -228,7 +228,7 @@ DormantNodeManager::RegisterAddOn(const char* path) int32 code; status = read_port(msg.reply_port, &code, &reply, sizeof(reply)); - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); if (status < B_OK) { ERROR("DormantNodeManager::RegisterAddon failed, couldn't talk to " @@ -269,11 +269,11 @@ DormantNodeManager::FindAddOnPath(BPath* path, media_addon_id id) server_get_mediaaddon_ref_request msg; msg.addon_id = id; - msg.reply_port = _PortPool->GetPort(); + msg.reply_port = gPortPool->GetPort(); status_t status = write_port(port, SERVER_GET_MEDIAADDON_REF, &msg, sizeof(msg)); if (status != B_OK) { - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return status; } @@ -281,7 +281,7 @@ DormantNodeManager::FindAddOnPath(BPath* path, media_addon_id id) int32 code; status = read_port(msg.reply_port, &code, &reply, sizeof(reply)); - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); if (status < B_OK) return status; diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index ce2b551ccd..3b95ddc388 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -1378,14 +1378,14 @@ BMediaRoster::SetProducerRate(const media_node& producer, int32 numer, msg.numer = numer; msg.denom = denom; - msg.reply_port = _PortPool->GetPort(); + msg.reply_port = gPortPool->GetPort(); rv = write_port(producer.node, PRODUCER_SET_PLAY_RATE, &msg, sizeof(msg)); if (rv != B_OK) { - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return rv; } rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return (rv < B_OK) ? rv : reply.result; } @@ -2298,11 +2298,11 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count, } msg.require_kinds = requireKinds; msg.deny_kinds = denyKinds; - msg.reply_port = _PortPool->GetPort(); + msg.reply_port = gPortPool->GetPort(); rv = write_port(port, SERVER_GET_DORMANT_NODES, &msg, sizeof(msg)); if (rv != B_OK) { - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return rv; } @@ -2311,7 +2311,7 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count, rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); if (rv < B_OK) { - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return rv; } @@ -2323,7 +2323,7 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count, if (rv < B_OK) reply.result = rv; } - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return reply.result; } @@ -2624,18 +2624,18 @@ BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID, xfer_server_get_dormant_flavor_info msg; msg.addon = addonID; msg.flavor_id = flavorID; - msg.reply_port = _PortPool->GetPort(); + msg.reply_port = gPortPool->GetPort(); status_t status = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg)); if (status != B_OK) { free(reply); - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); return status; } int32 code; status = read_port(msg.reply_port, &code, reply, 16000); - _PortPool->PutPort(msg.reply_port); + gPortPool->PutPort(msg.reply_port); if (status < B_OK) { free(reply); diff --git a/src/kits/media/PortPool.cpp b/src/kits/media/PortPool.cpp index 20e301878b..1cc036f6f3 100644 --- a/src/kits/media/PortPool.cpp +++ b/src/kits/media/PortPool.cpp @@ -1,88 +1,68 @@ -/*********************************************************************** - * Copyright (c) 2002 Marcus Overhagen. All Rights Reserved. - * This file may be used under the terms of the OpenBeOS License. - * - * A pool of kernel ports - ***********************************************************************/ -#include -#include -#include "PortPool.h" -#include "debug.h" +/* + * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include + + +namespace BPrivate { + + +static PortPool sPortPool; +PortPool* gPortPool = &sPortPool; -PortPool _ThePortPool; -PortPool *_PortPool = &_ThePortPool; PortPool::PortPool() + : + BLocker("port pool") { - locker_atom = 0; - locker_sem = create_sem(0,"port pool lock"); - count = 0; - maxcount = 0; - pool = 0; } + PortPool::~PortPool() { - for (int i = 0; i < maxcount; i++) - delete_port(pool[i].port); - delete_sem(locker_sem); - if (pool) - free(pool); + PortSet::iterator iterator = fPool.begin(); + + for (; iterator != fPool.end(); iterator++) + delete_port(*iterator); } -port_id + +port_id PortPool::GetPort() { - port_id port = -1; - Lock(); - if (count == maxcount) { - maxcount += 3; - pool = (PortInfo *)realloc(pool,sizeof(PortInfo) * maxcount); - if (pool == NULL) - debugger("out of memory in PortPool::GetPort()\n"); - for (int i = count; i < maxcount; i++) { - pool[i].used = false; - pool[i].port = create_port(1,"some reply port"); - } - } - count++; - for (int i = 0; i < maxcount; i++) - if (pool[i].used == false) { - port = pool[i].port; - pool[i].used = true; - break; - } - Unlock(); - if (port < 0) - debugger("wrong port in PortPool::GetPort()\n"); + BAutolock _(this); + + if (fPool.empty()) + return create_port(1, "media reply port"); + + port_id port = *fPool.begin(); + fPool.erase(port); + + ASSERT(port >= 0); return port; } + void PortPool::PutPort(port_id port) { - Lock(); - count--; - for (int i = 0; i < maxcount; i++) - if (pool[i].port == port) { - pool[i].used = false; - break; - } - Unlock(); -} + ASSERT(port >= 0); -void -PortPool::Lock() -{ - if (atomic_add(&locker_atom, 1) > 0) { - while (B_INTERRUPTED == acquire_sem(locker_sem)) - ; + BAutolock _(this); + + try { + fPool.insert(port); + } catch (std::bad_alloc& exception) { + delete_port(port); } } -void -PortPool::Unlock() -{ - if (atomic_add(&locker_atom, -1) > 1) - release_sem(locker_sem); -} + +} // namespace BPrivate