* Rewrote PortPool, and put it into the BPrivate namespace.

* Renamed global variable _PortPool to gPortPool.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34540 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-12-07 21:28:08 +00:00
parent 92c66394a2
commit 9834d875d0
5 changed files with 94 additions and 108 deletions
+28 -22
View File
@@ -1,35 +1,41 @@
/* /*
* Copyright 2002, Marcus Overhagen. All Rights Reserved. * Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _POOL_PORT_H_ #ifndef PORT_POOL_H
#define _POOL_PORT_H_ #define PORT_POOL_H
class PortPool { #include <set>
#include <Locker.h>
namespace BPrivate {
class PortPool : BLocker {
public: public:
PortPool(); PortPool();
~PortPool(); ~PortPool();
port_id GetPort(); port_id GetPort();
void PutPort(port_id port); void PutPort(port_id port);
private: private:
void Lock(); typedef std::set<port_id> PortSet;
void Unlock();
struct PortInfo { PortSet fPool;
port_id port;
bool used;
};
PortInfo * pool;
int count;
int maxcount;
int32 locker_atom;
sem_id locker_sem;
}; };
extern PortPool *_PortPool;
#endif extern PortPool* gPortPool;
} // namespace BPrivate
using BPrivate::gPortPool;
#endif // PORT_POOL_H
+4 -4
View File
@@ -179,7 +179,7 @@ QueryPort(port_id requestport, int32 msgcode, request_data *request, int request
status_t rv; status_t rv;
int32 code; int32 code;
request->reply_port = _PortPool->GetPort(); request->reply_port = gPortPool->GetPort();
rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); 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(); find_media_addon_server_port();
requestport = MediaAddonServerPort; requestport = MediaAddonServerPort;
} else { } else {
_PortPool->PutPort(request->reply_port); gPortPool->PutPort(request->reply_port);
return rv; return rv;
} }
rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT); rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT);
if (rv != B_OK) { if (rv != B_OK) {
ERROR("QueryPort: retrying write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv)); 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; return rv;
} }
} }
rv = read_port_etc(request->reply_port, &code, reply, replysize, B_RELATIVE_TIMEOUT, TIMEOUT); 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) { 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)); ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv));
+6 -6
View File
@@ -213,12 +213,12 @@ DormantNodeManager::RegisterAddOn(const char* path)
return 0; return 0;
} }
msg.reply_port = _PortPool->GetPort(); msg.reply_port = gPortPool->GetPort();
msg.ref = ref; msg.ref = ref;
status = write_port(port, SERVER_REGISTER_MEDIAADDON, &msg, sizeof(msg)); status = write_port(port, SERVER_REGISTER_MEDIAADDON, &msg, sizeof(msg));
if (status != B_OK) { if (status != B_OK) {
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
ERROR("DormantNodeManager::RegisterAddon failed, couldn't talk to " ERROR("DormantNodeManager::RegisterAddon failed, couldn't talk to "
"media server\n"); "media server\n");
return 0; return 0;
@@ -228,7 +228,7 @@ DormantNodeManager::RegisterAddOn(const char* path)
int32 code; int32 code;
status = read_port(msg.reply_port, &code, &reply, sizeof(reply)); status = read_port(msg.reply_port, &code, &reply, sizeof(reply));
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
if (status < B_OK) { if (status < B_OK) {
ERROR("DormantNodeManager::RegisterAddon failed, couldn't talk to " 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; server_get_mediaaddon_ref_request msg;
msg.addon_id = id; 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, status_t status = write_port(port, SERVER_GET_MEDIAADDON_REF, &msg,
sizeof(msg)); sizeof(msg));
if (status != B_OK) { if (status != B_OK) {
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
return status; return status;
} }
@@ -281,7 +281,7 @@ DormantNodeManager::FindAddOnPath(BPath* path, media_addon_id id)
int32 code; int32 code;
status = read_port(msg.reply_port, &code, &reply, sizeof(reply)); status = read_port(msg.reply_port, &code, &reply, sizeof(reply));
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
if (status < B_OK) if (status < B_OK)
return status; return status;
+10 -10
View File
@@ -1378,14 +1378,14 @@ BMediaRoster::SetProducerRate(const media_node& producer, int32 numer,
msg.numer = numer; msg.numer = numer;
msg.denom = denom; 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)); rv = write_port(producer.node, PRODUCER_SET_PLAY_RATE, &msg, sizeof(msg));
if (rv != B_OK) { if (rv != B_OK) {
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
return rv; return rv;
} }
rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); 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; return (rv < B_OK) ? rv : reply.result;
} }
@@ -2298,11 +2298,11 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
} }
msg.require_kinds = requireKinds; msg.require_kinds = requireKinds;
msg.deny_kinds = denyKinds; 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)); rv = write_port(port, SERVER_GET_DORMANT_NODES, &msg, sizeof(msg));
if (rv != B_OK) { if (rv != B_OK) {
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
return rv; return rv;
} }
@@ -2311,7 +2311,7 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
if (rv < B_OK) { if (rv < B_OK) {
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
return rv; return rv;
} }
@@ -2323,7 +2323,7 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
if (rv < B_OK) if (rv < B_OK)
reply.result = rv; reply.result = rv;
} }
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
return reply.result; return reply.result;
} }
@@ -2624,18 +2624,18 @@ BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID,
xfer_server_get_dormant_flavor_info msg; xfer_server_get_dormant_flavor_info msg;
msg.addon = addonID; msg.addon = addonID;
msg.flavor_id = flavorID; 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, status_t status = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg,
sizeof(msg)); sizeof(msg));
if (status != B_OK) { if (status != B_OK) {
free(reply); free(reply);
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
return status; return status;
} }
int32 code; int32 code;
status = read_port(msg.reply_port, &code, reply, 16000); status = read_port(msg.reply_port, &code, reply, 16000);
_PortPool->PutPort(msg.reply_port); gPortPool->PutPort(msg.reply_port);
if (status < B_OK) { if (status < B_OK) {
free(reply); free(reply);
+45 -65
View File
@@ -1,88 +1,68 @@
/*********************************************************************** /*
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved. * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the OpenBeOS License. * Distributed under the terms of the MIT License.
* */
* A pool of kernel ports
***********************************************************************/
#include <OS.h> #include <PortPool.h>
#include <stdlib.h>
#include "PortPool.h" #include <Autolock.h>
#include "debug.h"
#include <debug.h>
namespace BPrivate {
static PortPool sPortPool;
PortPool* gPortPool = &sPortPool;
PortPool _ThePortPool;
PortPool *_PortPool = &_ThePortPool;
PortPool::PortPool() PortPool::PortPool()
:
BLocker("port pool")
{ {
locker_atom = 0;
locker_sem = create_sem(0,"port pool lock");
count = 0;
maxcount = 0;
pool = 0;
} }
PortPool::~PortPool() PortPool::~PortPool()
{ {
for (int i = 0; i < maxcount; i++) PortSet::iterator iterator = fPool.begin();
delete_port(pool[i].port);
delete_sem(locker_sem); for (; iterator != fPool.end(); iterator++)
if (pool) delete_port(*iterator);
free(pool);
} }
port_id port_id
PortPool::GetPort() PortPool::GetPort()
{ {
port_id port = -1; BAutolock _(this);
Lock();
if (count == maxcount) { if (fPool.empty())
maxcount += 3; return create_port(1, "media reply port");
pool = (PortInfo *)realloc(pool,sizeof(PortInfo) * maxcount);
if (pool == NULL) port_id port = *fPool.begin();
debugger("out of memory in PortPool::GetPort()\n"); fPool.erase(port);
for (int i = count; i < maxcount; i++) {
pool[i].used = false; ASSERT(port >= 0);
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");
return port; return port;
} }
void void
PortPool::PutPort(port_id port) PortPool::PutPort(port_id port)
{ {
Lock(); ASSERT(port >= 0);
count--;
for (int i = 0; i < maxcount; i++)
if (pool[i].port == port) {
pool[i].used = false;
break;
}
Unlock();
}
void BAutolock _(this);
PortPool::Lock()
{ try {
if (atomic_add(&locker_atom, 1) > 0) { fPool.insert(port);
while (B_INTERRUPTED == acquire_sem(locker_sem)) } catch (std::bad_alloc& exception) {
; delete_port(port);
} }
} }
void
PortPool::Unlock() } // namespace BPrivate
{
if (atomic_add(&locker_atom, -1) > 1)
release_sem(locker_sem);
}