* 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

View File

@ -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 <set>
#include <Locker.h>
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<port_id> 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

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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 <OS.h>
#include <stdlib.h>
#include "PortPool.h"
#include "debug.h"
/*
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <PortPool.h>
#include <Autolock.h>
#include <debug.h>
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