Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/corelibs/vos/localsite.hh

Go to the documentation of this file.
00001 /*
00002     This file is part of the Virtual Object System of
00003     the Interreality project (http://interreality.org).
00004 
00005     Copyright (C) 2001-2003 Peter Amstutz
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020 
00021     Peter Amstutz <tetron@interreality.org>
00022 */
00023 #ifndef _LOCALSITE_HH_
00024 #define _LOCALSITE_HH_
00025 
00026 #include <vos/corelibs/vos/vosdefs.hh>
00027 #include <vos/corelibs/vos/site.hh>
00028 #include <vos/corelibs/vos/localmetaobject.hh>
00029 
00030 #include <map>
00031 #include <queue>
00032 #include <iostream>
00033 
00034 namespace VOS
00035 {
00036     class RemoteSite;
00037     class RemoteSocketSite; // Why does localsite use both remotesocketsite and remotesite?
00038 
00039 typedef MetaObject* (*metaobject_extender_t)(MetaObject* superobject, const string& type);
00040 
00041 /** @class LocalSite localsite.hh vos/corelibs/vos/localsite.hh
00042  *
00043  * A site which is local to your application.  This acts as the
00044     communication point between your application and other VOS
00045     applications, managing the delivery of incoming messages as well
00046     as servicing certain types of requests about your local Vobjects.
00047     All Vobjects are associated with some site.
00048 */
00049 class VOS_API LocalSite : public virtual Site, public virtual LocalMetaObject
00050 {
00051 private:
00052     typedef multimap<string, metaobject_extender_t>::iterator MI;
00053     static multimap<string, metaobject_extender_t> localObjectExtensionTable;
00054 public:
00055     class PortBindingError : public runtime_error {
00056     public:
00057         PortBindingError(const string& s) : runtime_error(s) { }
00058     };
00059 protected:
00060     struct SiteTableEntry {
00061         string localPeerName;
00062         MessageBlock* partialMessage;
00063     };
00064     int iteratorsUsingPeerSites;
00065 
00066     /** The following three data structures are used to buffer changes
00067        to peerSites when we have an active iterator using peerSites.
00068        This is to avoid invalidating the iterator (ye gods that was an
00069        obnoxious bug to track down.)  The alternative would have to be
00070        to make a complete copy of the peerSites deque every time we
00071        want to copy it (ewww...)
00072 
00073        @note although peerSitesBuffer_rs and peerSitesBuffer_st could
00074        be combined into a single structure like deque<
00075        pair<RemoteSite*, struct SiteTableEntry*> > BUT that causes an
00076        internal compiler error when compiling site.cc!  So instead we
00077        do it this way.  Bleh.
00078     */
00079     deque<RemoteSite*> peerSitesBuffer_rs;
00080     deque<struct SiteTableEntry*> peerSitesBuffer_st;
00081     deque<RemoteSite*> peerSitesBuffer_remove;
00082 
00083     boost::mutex peerSitesBuffer_mutex;
00084 
00085     /** List of remote sites we are peers with. */
00086     map<RemoteSite*, struct SiteTableEntry*> peerSites;
00087 
00088     /** The current message schedule. */
00089     map<double, list<Message*> > siteMessageQueue;
00090     list<Message*> msgsReady;
00091     list<Message*> prioritizedQueue;
00092 
00093     struct ::timeval* selectwait;
00094 
00095     map<string, RemoteSite*> prioritized;
00096 
00097 public:
00098     
00099     /** Timer callback type for a global C function. Register the callback
00100      * using addCallback. 
00101      */
00102     typedef void (*callback_t)(void* userdata);
00103     
00104     /** Timer callback listener type. Register an instance of this class
00105      * using addCallback.
00106      */
00107     class CallbackListener {
00108     public:
00109         virtual void notifySiteCallback() = 0;
00110     };
00111 
00112 protected:
00113     struct CallbackInfo {
00114         bool repeat;    // callback should be performed repeatedly
00115         double timeout; // amount of time to wait between repeated callbacks
00116         callback_t callback;    // if null, try listener
00117         void* userdata;
00118         CallbackListener* listener; // if null, try callback function.
00119     };
00120 
00121     bool callbacklock;
00122     map<double, CallbackInfo> callbacks;
00123     queue<pair<double, CallbackInfo> > callbackaddqueue;
00124     queue<callback_t> callbackremovequeue;
00125     queue<CallbackListener*> callback_listener_remove_queue;
00126     void scheduleCallback(callback_t callback, CallbackListener* listener, void* userdata, double timeout, bool repeat);
00127 
00128     queue<NotifyEvent*> notifyEvents;
00129     bool notifyflushlock;
00130 
00131     map<string, string> antiSpoofMap;
00132 
00133     void verifyCheckIDPair(RemoteSocketSite* rss, const string& spoofID);
00134 
00135     struct ValidationEntry
00136     {
00137         string checkid;
00138         string hostalias;
00139         vRef<RemoteSocketSite> realsite;
00140         bool favored;
00141     };
00142     map<RemoteSocketSite*, ValidationEntry> pendingValidations;
00143     set<string> pendingValidationHosts;
00144 
00145     list< pair<string, RemoteSite*> > needSpoofIDreply;
00146 
00147     /** constructor */
00148     LocalSite();
00149 public:
00150     /** destructor */
00151     virtual ~LocalSite();
00152 
00153     virtual void flushIncomingBuffers() = 0;
00154 
00155     /** Schedule a message block for delivery.  Special message types like include
00156         will be processed.
00157         @param mb The message block
00158         @param mc The enclosing message context
00159         @param ss The source site
00160         @param plustime This value will be added to the delivery time
00161         @param extradependency This dependency string will added to each message
00162     */
00163     virtual void scheduleMessageBlock(MessageBlock* mb, MessageContext* mc, Site* ss,
00164                                       double plustime=0.0, const char* extradependency=0);
00165 
00166     /** Execute the current schedule.  */
00167     virtual void runSchedule();
00168 
00169     /** Run pending callbacks. */
00170     void doCallbacks();
00171 
00172     /** Register a periodic or timed callback listener. Callbacks are 
00173      * checked each time flushIncomingBuffers is called. 
00174     */
00175     void addCallback(CallbackListener* listener, double timeout, bool repeat = true);
00176 
00177     /** Register a simple global function as a timer callback. */
00178     void addCallback(callback_t callback, void* userdata, double timeout, bool repeat = true);
00179 
00180     /** Remove a callback. (see addCallback)*/
00181     void removeCallback(callback_t callback);
00182 
00183     /** Remove a callback. (see addCallback)*/
00184     void removeCallback(CallbackListener* listener);
00185 
00186     /** Remove the peering relationship with a remote site. */
00187     virtual void removeRemotePeer(RemoteSite* rs);
00188 
00189     /** Check if any messages in the schedule have "site" as a source
00190         site.  Mainly used when a site disconnects and its pending
00191         messages need to be flushed...
00192     */
00193     virtual bool checkScheduleHoldsSite(Site* site);
00194 
00195     virtual void sendMessage(Message* m);
00196     virtual void sendMessage(MessageBlock* m);
00197     virtual void setURL(const URL& u);
00198 
00199     /** Always true. */
00200     virtual bool isConnected() {
00201         return true;
00202     }
00203 
00204     virtual Site& getSite() { return Site::getSite(); }
00205 
00206     /** When select() is called to test file descriptors, this sets maximum amount of time
00207         to wait before returning if there is no data available.  This primarily applies
00208         to LocalSite::flushIncomingBuffers().
00209         @param sec the time to wait, in seconds.  This may be zero, in
00210         which case a flushIncomingBuffers() call will return
00211         immediately if there is no pending data.  If "sec" is
00212         negative, select will sleep indefinitely until data is
00213         received on any of the sockets or the process catches a
00214         signal.
00215     */
00216     void setTimeoutOnSelect(double sec);
00217 
00218     /** Get the select wait time.
00219         @return the maximum time (in seconds) that select will wait,
00220         or -1 if select will block indefinately. */
00221     double getTimeoutOnSelect();
00222 
00223     virtual void addPrioritizedNonce(const string& nonce, RemoteSite* source);
00224     virtual void removePrioritizedNonce(const string& nonce, RemoteSite* source);
00225 
00226     /** Use this site to extend a LocalMetaObject with for a new type. */
00227     static void extendMetaObject(LocalMetaObject* root, const char* type);
00228 
00229     /** Create meta objects with the given name and types, and the default
00230         access control for this site.  */
00231     //@{
00232     /** Use 0 to terminate the list of type strings. */
00233     virtual MetaObject* createMetaObject(const char* name, const char* type0, ...);
00234     virtual MetaObject* createMetaObject(const char* name, const deque<string>& typelist);
00235     //@}
00236 
00237     /** Create a new local metaobject, with the supplied access control (ar
00238      * defoult site AC if 0).
00239      * @sa createMetaObject(const char*, const char*, ...)
00240      */
00241     virtual MetaObject* createMetaObject(const char* name, VobjectAccessControl* ac, const char* type0, ...);
00242 
00243 
00244     /** Create a new local metaobject, with the supplied access control (ar
00245      * defoult site AC if 0).
00246      * @sa createMetaObject(const char*, const char*, ...)
00247      */
00248     virtual MetaObject* createMetaObject(const char* name, VobjectAccessControl* ac, const deque<string>& typelist);
00249 
00250 
00251     /** Create a new metaobject with one type, and cast it to that type.
00252      * @param T     Desired MetaObject subclass
00253      * @param name  If given, site-name of the new object
00254      * @param ac    Primary access control on the new object
00255      */ 
00256     template<class T> T* createMetaObject(const char* name = 0, VobjectAccessControl* ac = 0) {
00257         if(ac)
00258             return meta_cast<T*>(createMetaObject(name, ac, typeid(T).name(), 0));
00259         else
00260             return meta_cast<T*>(createMetaObject(name, typeid(T).name(), 0));
00261     }
00262 
00263 
00264     static void addLocalObjectExtension(const char* type, metaobject_extender_t newmethod);
00265     static void removeLocalObjectExtension(const char* type, metaobject_extender_t oldmethod);
00266 
00267     static void printExtensionTable(ostream& stream = std::cerr);
00268 
00269     /** Add a notification event to be called during
00270         flushIncomingBuffers().  A notification event is called once
00271         and then destroyed.
00272      */
00273     virtual void addNotification(NotifyEvent* ev);
00274 
00275     /** Execute any pending notification events. */
00276     virtual void flushNotifications();
00277 
00278     /** Calling this will cause flushNotifications() to do nothing
00279         (and hence no notifications will be processed) until
00280         unlockNotificationFlush is called. */
00281     virtual void lockNotificationFlush();
00282 
00283     /** Allow notifcations to be processed again. */
00284     virtual void unlockNotificationFlush();
00285 
00286     virtual void insertChild(int position, const string& contextual_name, Vobject* child)
00287         throw (AccessControlError, RemoteError);
00288     virtual void setChild(int position, const string& contextual_name, Vobject* child)
00289         throw (AccessControlError, RemoteError);
00290     virtual void removeChild(int position)
00291         throw (AccessControlError, RemoteError);
00292 
00293     /** Maps a received anti-spoof ID to the one sent to that site. */
00294     void setAntiSpoofIDMapping(const string& recv, const string& sent) { antiSpoofMap[recv] = sent; }
00295 
00296     /** Maps a received anti-spoof ID to the one sent to that site. */
00297     const string& getAntiSpoofIDMapping(const string& recv) { return antiSpoofMap[recv]; }
00298 
00299     /** Any messages belonging to site "was" will be reassigned to
00300         site "now".  This only affects the source site field of the
00301         message object.
00302     */
00303     void takeOverMessages(Site* was, Site* now);
00304 
00305     /** Set the hostname we will prefer to use.
00306         @param s the DNS hostname or dotted quad IP address */
00307     virtual void setPrimaryHostname(string s);
00308 
00309     friend void Site::doSitePeering(LocalSite* localsite, RemoteSite* remotesite, bool isspooftest, bool waitforhello);
00310 };
00311 }
00312 
00313 #endif

Generated on Tue Aug 12 03:55:40 2003 for Interreality Project - VOS by doxygen 1.3.2