xorp

selector.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU Lesser General Public License, Version
00008 // 2.1, June 1999 as published by the Free Software Foundation.
00009 // Redistribution and/or modification of this program under the terms of
00010 // any other version of the GNU Lesser General Public License is not
00011 // permitted.
00012 // 
00013 // This program is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00016 // see the GNU Lesser General Public License, Version 2.1, a copy of
00017 // which can be found in the XORP LICENSE.lgpl file.
00018 // 
00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00020 // http://xorp.net
00021 
00022 
00023 #ifndef __LIBXORP_SELECTOR_HH__
00024 #define __LIBXORP_SELECTOR_HH__
00025 
00026 #ifdef HAVE_SYS_TYPES_H
00027 #include <sys/types.h>
00028 #endif
00029 #ifdef HAVE_SYS_TIME_H
00030 #include <sys/time.h>
00031 #endif
00032 #ifdef HAVE_UNISTD_H
00033 #include <unistd.h>
00034 #endif
00035 
00036 #include "libxorp/xorp.h"
00037 
00038 #ifndef USE_WIN_DISPATCHER
00039 
00040 #include "callback.hh"
00041 #include "ioevents.hh"
00042 #include "task.hh"
00043 
00044 class ClockBase;
00045 class SelectorList;
00046 class TimeVal;
00047 
00048 
00052 enum SelectorMask {
00053     SEL_NONE    = 0x0,              // No events
00054     SEL_RD  = 0x01,             // Read events
00055     SEL_WR  = 0x02,             // Write events
00056     SEL_EX  = 0x04,             // Exception events
00057     SEL_ALL = SEL_RD | SEL_WR | SEL_EX  // All events
00058 };
00059 
00060 class SelectorTag;
00061 
00062 typedef ref_ptr<SelectorTag> Selector;
00063 
00072 class SelectorListObserverBase {
00073 public:
00074     virtual ~SelectorListObserverBase();
00075 
00076 private:
00081     virtual void notify_added(XorpFd fd, const SelectorMask& mask) = 0;
00082 
00087     virtual void notify_removed(XorpFd fd, const SelectorMask& mask) = 0;
00088 
00089     SelectorList * _observed;
00090 
00091     friend class SelectorList;
00092 };
00093 
00102 class SelectorList :
00103     public NONCOPYABLE
00104 {
00105 public:
00106 
00110     SelectorList(ClockBase* clock);
00111 
00115     virtual ~SelectorList();
00116 
00117     void set_debug(bool v) { _is_debug = v;}
00118     bool is_debug() const { return (_is_debug); }
00119 
00142      bool add_ioevent_cb(XorpFd     fd, 
00143              IoEventType    type, 
00144              const IoEventCb& cb,
00145              int        priority = XorpTask::PRIORITY_DEFAULT);
00146 
00155     void remove_ioevent_cb(XorpFd fd, IoEventType type = IOT_ANY);
00156 
00162     bool ready();
00163 
00169     int get_ready_priority(bool force);
00170 
00179     int wait_and_dispatch(TimeVal& timeout);
00180 
00189     int wait_and_dispatch(int millisecs);
00190 
00196     size_t descriptor_count() const { return _descriptor_count; }
00197 
00206      void get_fd_set(SelectorMask selected_mask, fd_set& fds) const;
00207 
00213      int get_max_fd() const;
00214 
00220      void set_observer(SelectorListObserverBase& obs);
00221 
00227      void remove_observer();
00228 
00229 
00230 protected:
00231     void callback_bad_descriptors();
00232 
00233 private:
00234     int do_select(struct timeval* to, bool force);
00235 
00236 private:
00237     enum {
00238     // correspond to SelectorMask; correspondence checked with
00239     // x_static_assert
00240     SEL_RD_IDX  = 0,
00241     SEL_WR_IDX  = 1,
00242     SEL_EX_IDX  = 2,
00243     SEL_MAX_IDX = 3
00244     };
00245 
00246     #define GOOD_NODE_MAGIC 0x12345678
00247     struct Node {
00248     int magic; // catch memory errors.
00249     int     _mask[SEL_MAX_IDX];
00250     IoEventCb   _cb[SEL_MAX_IDX];
00251     // Reverse mapping of legacy UNIX event to IoEvent
00252     IoEventType _iot[SEL_MAX_IDX];
00253     int     _priority[SEL_MAX_IDX];
00254 
00255     Node();
00256     ~Node();
00257     Node(const Node& rhs); // copy constructor
00258     Node& operator=(const Node& rhs); // operator= overload
00259 
00260     bool        add_okay(SelectorMask m, IoEventType type,
00261                  const IoEventCb& cb, int priority);
00262     int     run_hooks(SelectorMask m, XorpFd fd);
00263     void        clear(SelectorMask m);
00264     bool        is_empty();
00265     };
00266 
00267     ClockBase*      _clock;
00268     SelectorListObserverBase * _observer;
00269     fd_set      _fds[SEL_MAX_IDX];
00270     fd_set      _testfds[SEL_MAX_IDX];
00271     int         _testfds_n;
00272     int         _maxpri_fd;
00273     int         _maxpri_sel;
00274     int         _last_served_fd;
00275     int         _last_served_sel;
00276 
00277     vector<Node>    _selector_entries;
00278     int         _maxfd;
00279     size_t      _descriptor_count;
00280     bool        _is_debug;
00281 };
00282 #endif // USE_WIN_DISPATCHER
00283 #endif // __LIBXORP_SELECTOR_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations