* 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:
parent
92c66394a2
commit
9834d875d0
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user