]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_utilities/lib/selector.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_utilities / lib / selector.cpp
diff --git a/libsecurity_utilities/lib/selector.cpp b/libsecurity_utilities/lib/selector.cpp
deleted file mode 100644 (file)
index d636ac7..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-//
-// selector - I/O stream multiplexing
-//
-#include "selector.h"
-#include <security_utilities/errors.h>
-#include <security_utilities/debugging.h>
-#include <algorithm>   // min/max
-
-
-namespace Security {
-namespace UnixPlusPlus {
-
-
-//
-// construct a Selector object.
-//
-Selector::Selector() : fdMin(INT_MAX), fdMax(-1)
-{
-    // initially allocate room for FD_SETSIZE file descriptors (usually good enough)
-    fdSetSize = FD_SETSIZE / NFDBITS;
-    inSet.grow(0, fdSetSize);
-    outSet.grow(0, fdSetSize);
-    errSet.grow(0, fdSetSize);
-}
-
-Selector::~Selector()
-{ }
-
-
-//
-// Add a Client to a Selector
-//
-void Selector::add(int fd, Client &client, Type type)
-{
-    // plausibility checks
-    assert(!client.isActive());                // one Selector per client, and no re-adding
-    assert(fd >= 0);
-    
-    secdebug("selector", "add client %p fd %d type=%d", &client, fd, type);
-    
-    // grow FDSets if needed
-    unsigned int pos = fd / NFDBITS;
-    if (pos >= fdSetSize) {
-        int newSize = (fd - 1) / NFDBITS + 2;  // as much as needed + 1 spare word
-        inSet.grow(fdSetSize, newSize);
-        outSet.grow(fdSetSize, newSize);
-        errSet.grow(fdSetSize, newSize);
-    }
-    
-    // adjust boundaries
-    if (fd < fdMin)
-        fdMin = fd;
-    if (fd > fdMax)
-        fdMax = fd;
-
-    // add client
-    Client * &slot = clientMap[fd];
-    assert(!slot);
-    slot = &client;
-    client.mFd = fd;
-    client.mSelector = this;
-    client.mEvents = type;
-    set(fd, type);
-}    
-
-
-//
-// Remove a Client from a Selector
-//
-void Selector::remove(int fd)
-{
-    // sanity checks
-    assert(fd >= 0);
-    ClientMap::iterator it = clientMap.find(fd);
-    assert(it != clientMap.end());
-    assert(it->second->mSelector == this);
-
-    secdebug("selector", "remove client %p fd %d", it->second, fd);
-
-    // remove from FDSets
-    set(fd, none);
-    
-    // remove client
-    it->second->mSelector = NULL;
-    clientMap.erase(it);
-    
-    // recompute fdMin/fdMax if needed
-    if (isEmpty()) {
-        fdMin = INT_MAX;
-        fdMax = -1;
-    } else if (fd == fdMin) {
-        fdMin = clientMap.begin()->first;
-    } else if (fd == fdMax) {
-        fdMax = clientMap.rbegin()->first;
-    }
-}
-
-
-//
-// Adjust the FDSets for a single given Client according to a new event Type mask.
-//
-void Selector::set(int fd, Type type)
-{
-    assert(fd >= 0);
-    inSet.set(fd, type & input);
-    outSet.set(fd, type & output);
-    errSet.set(fd, type & critical);
-    secdebug("selector", "fd %d notifications 0x%x", fd, type);
-}
-
-
-void Selector::operator () ()
-{
-    if (!clientMap.empty())
-        singleStep(0);
-}
-
-
-void Selector::operator () (Time::Absolute stopTime)
-{
-    if (!clientMap.empty())
-        singleStep(stopTime - Time::now());
-}
-
-
-//
-// Perform a single pass through the Selector and notify all clients
-// that have selected I/O pending at this time.
-// There is not time limit on how long this may take; if the clients
-// are well written, it won't be too long.
-//
-void Selector::singleStep(Time::Interval maxWait)
-{
-    assert(!clientMap.empty());
-    secdebug("selector", "select(%d) [%d-%d] for %ld clients",
-        fdMax + 1, fdMin, fdMax, clientMap.size());
-    for (;;) { // pseudo-loop - only retries
-        struct timeval duration = maxWait.timevalInterval();
-#if defined(__APPLE__)
-        // ad-hoc fix: MacOS X's BSD rejects times of more than 100E6 seconds
-        if (duration.tv_sec > 100000000)
-            duration.tv_sec = 100000000;
-#endif
-        const int size = FDSet::words(fdMax);          // number of active words in sets
-        switch (int hits = ::select(fdMax + 1,
-                inSet.make(size), outSet.make(size), errSet.make(size),
-                &duration)) {
-        case -1:               // error
-            if (errno == EINTR)
-                continue;
-            secdebug("selector", "select failed: errno=%d", errno);
-            UnixError::throwMe();
-        case 0:                        // no events
-            secdebug("selector", "select returned nothing");
-            return;
-        default:               // some events
-            secdebug("selector", "%d pending descriptors", hits);
-            //@@@ This could be optimized as a word-merge scan.
-            //@@@ The typical case doesn't benefit from this though, though browsers might
-            //@@@ and integrated servers definitely would.
-            for (int fd = fdMin; fd <= fdMax && hits > 0; fd++) {
-                int types = 0;
-                if (inSet[fd])  types |= input;
-                if (outSet[fd]) types |= output;
-                if (errSet[fd]) types |= critical;
-                if (types) {
-                    secdebug("selector", "notify fd %d client %p type %d",
-                        fd, clientMap[fd], types);
-                    clientMap[fd]->notify(fd, types);
-                    hits--;
-                }
-            }
-            return;
-        }
-    }
-}
-
-
-}      // end namespace IPPlusPlus
-}      // end namespace Security