/*********************************************************************** * 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" PortPool _ThePortPool; PortPool *_PortPool = &_ThePortPool; PortPool::PortPool() { 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); } 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 int PortPool::GetPort()\n"); 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(); } void PortPool::Lock() { if (atomic_add(&locker_atom, 1) > 0) { while (B_INTERRUPTED == acquire_sem(locker_sem)) ; } } void PortPool::Unlock() { if (atomic_add(&locker_atom, -1) > 1) release_sem(locker_sem); }