// $Source: bitbucket.org:berkeleylab/gasnet.git/other/amudp/socklist.cpp $ // Description: // Copyright 2000, Dan Bonachea #include #include "socklist.h" #ifdef SOCKLIST_MT semaphore SocketList::lock("socketlist"); #define LOCK do { if (TS) lock.wait(); } while (0) #define UNLOCK do { if (TS) lock.signal(); } while (0) #else #define LOCK #define UNLOCK #endif SocketList::SocketList(unsigned long maxsize, bool ThreadSafe) { size = maxsize; table = new SOCKET[maxsize]; count = 0; maxfd = 0; FD_ZERO(&prvSet); TS = ThreadSafe; } SocketList::~SocketList() { delete table; } void SocketList::clear() { LOCK; count = 0; maxfd = 0; FD_ZERO(&prvSet); UNLOCK; return; } bool SocketList::insert(SOCKET s) { LOCK; if (count >= size) { UNLOCK; return false; } if (prvlookup(s)) { UNLOCK; return false; } table[count] = s; count++; if (s > maxfd) maxfd = s; FD_SET(s, &prvSet); UNLOCK; return true; } bool SocketList::remove(SOCKET s) { LOCK; for (unsigned long i=0; i < count; i++) { if (table[i] == s) { table[i] = table[--count]; FD_CLR(s, &prvSet); if (maxfd == s) { maxfd = 0; for (unsigned long j=0; j < count; j++) { if (table[j] > maxfd) maxfd = table[j]; } } UNLOCK; return true; } } UNLOCK; return false; } SOCKET SocketList::operator[](unsigned long index) { // note: data gets rearranged on insert/remove assert(index < count && !TS); return table[index]; } bool SocketList::prvlookup(SOCKET s) { for (unsigned long i=0; i < count; i++) if (table[i] == s) return true; return false; } bool SocketList::lookup(SOCKET s) { LOCK; bool retval = prvlookup(s); UNLOCK; return retval; } fd_set* SocketList::makeFD_SET(fd_set* set) { LOCK; memcpy(set, &prvSet, sizeof(fd_set)); UNLOCK; return set; } int SocketList::getIntersection(fd_set* set, SOCKET* buffer, int bufsiz) { getIntersection(set, buffer, &bufsiz); return bufsiz; } SOCKET* SocketList::getIntersection(fd_set* set, SOCKET* buffer, int* sz) { LOCK; // writes a list of sockets that appear in this list and set into buffer unsigned long cur = 0; for (unsigned long i=0; i < count && cur < (unsigned long)*sz; i++) { if (FD_ISSET(table[i], set)) { buffer[cur++] = table[i]; } } *sz = cur; UNLOCK; return buffer; } SocketList::SocketList(SocketList& other) { // copy ctr #ifdef SOCKLIST_MT int locked = (TS || other.TS); if (locked) lock.wait(); #endif count = other.count; maxfd = other.maxfd; size = other.size; table = new SOCKET[size]; for (unsigned long i=0; i < count; i++) { table[i] = other.table[i]; } memcpy(&prvSet,&other.prvSet,sizeof(fd_set)); #ifdef SOCKLIST_MT if (locked) lock.signal(); #endif }