* 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:
@@ -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
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
+46
-66
@@ -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);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user