1 /*********************************************************************** 2 * Copyright (c) 2002 Marcus Overhagen. All Rights Reserved. 3 * This file may be used under the terms of the OpenBeOS License. 4 * 5 * A pool of kernel ports 6 ***********************************************************************/ 7 #include <OS.h> 8 #include <stdlib.h> 9 #include "PortPool.h" 10 #include "debug.h" 11 12 PortPool _ThePortPool; 13 PortPool *_PortPool = &_ThePortPool; 14 15 PortPool::PortPool() 16 { 17 locker_atom = 0; 18 locker_sem = create_sem(0,"port pool lock"); 19 count = 0; 20 maxcount = 0; 21 pool = 0; 22 } 23 24 PortPool::~PortPool() 25 { 26 for (int i = 0; i < maxcount; i++) 27 delete_port(pool[i].port); 28 delete_sem(locker_sem); 29 if (pool) 30 free(pool); 31 } 32 33 port_id 34 PortPool::GetPort() 35 { 36 port_id port = -1; 37 Lock(); 38 if (count == maxcount) { 39 maxcount += 3; 40 pool = (PortInfo *)realloc(pool,sizeof(PortInfo) * maxcount); 41 if (pool == NULL) 42 debugger("out of memory in PortPool::GetPort()\n"); 43 for (int i = count; i < maxcount; i++) { 44 pool[i].used = false; 45 pool[i].port = create_port(1,"some reply port"); 46 } 47 } 48 count++; 49 for (int i = 0; i < maxcount; i++) 50 if (pool[i].used == false) { 51 port = pool[i].port; 52 pool[i].used = true; 53 break; 54 } 55 Unlock(); 56 if (port < 0) 57 debugger("wrong port int PortPool::GetPort()\n"); 58 return port; 59 } 60 61 void 62 PortPool::PutPort(port_id port) 63 { 64 Lock(); 65 count--; 66 for (int i = 0; i < maxcount; i++) 67 if (pool[i].port == port) { 68 pool[i].used = false; 69 break; 70 } 71 Unlock(); 72 } 73 74 void 75 PortPool::Lock() 76 { 77 if (atomic_add(&locker_atom, 1) > 0) { 78 while (B_INTERRUPTED == acquire_sem(locker_sem)) 79 ; 80 } 81 } 82 83 void 84 PortPool::Unlock() 85 { 86 if (atomic_add(&locker_atom, -1) > 1) 87 release_sem(locker_sem); 88 } 89