threading-model.h

Go to the documentation of this file.
00001 /*
00002  * threading-model.h
00003  *
00004  * This isn't a real header!
00005  *
00006  * This is just here for doxygen documentation.
00007  */
00008 
00009 /// \ingroup aesop_srv
00010 /*{@*/
00011 
00012 
00013 /// \defgroup aesop_srv_thread Server Threading Model
00014 ///
00015 /// The AESOP Server is designed to be multithreaded.  This is important so
00016 /// that the server can handle long-latency operations (reading files, etc.)
00017 /// without impacting the core processing loop.
00018 ///
00019 /// In general, the main thread of execution (the startup thread) is what
00020 /// performs the main processing loop.  The server object, and other objects,
00021 /// have helper threads to do asynchronous processing.  The general pattern is
00022 /// that someone requests work to be done (TCP message from client, or rules
00023 /// engine requesting a map be loaded), and the request is queued.  Worker
00024 /// threads check the queue, perform the work, and either queue the result or
00025 /// know how to update state appropriately by updating threadsafe data
00026 /// collections.
00027 ///
00028 /// Objects with helper threads should maintain thread pools (or a single
00029 /// helper thread), and NOT spin off threads as needed.  This requires queuing
00030 /// of requests, but helps prevent runaway thread creation.  If a request queue
00031 /// gets too long, further requests should be denied.  Clients (remote or local)
00032 /// should be able to handle request failure gracefully.
00033 ///
00034 /// However, threading carries penalties and dangers as well.  The main
00035 /// penalty is that data shared between threads needs to be synchronized.  In
00036 /// general, all data on the heap that could be shared is synchronized using
00037 /// threadsafe collections from the Wavepacket Threadsafe Library:
00038 /// http://wavepacket-lib.sourceforge.net/group__threadsafe.html
00039 ///
00040 ///
00041 /// \n
00042 /// The dangers of threading are related to that.  Any important data that
00043 /// isn't protected could result in program crashes or other misbehavior.
00044 /// There, the solution is simple: any data that could be accessed by
00045 /// multiple threads must be protected!  More concretely, any data on the
00046 /// heap must be protected by a threadsafe collection.
00047 ///
00048 /// The other danger is deadlocks.  See http://en.wikipedia.org/wiki/Deadlock .
00049 /// That article gives a good overview of how deadlocks can occur, and how to
00050 /// avoid them.
00051 ///
00052 /// <b>The AESOP Server takes a simple approach,</b> which the wiki page describes
00053 /// as eliminating the "hold and wait" condition.  In the AESOP Server, the
00054 /// only locks allowed to exist are on the threadsafe collections.  Threads
00055 /// should never directly lock or unlock mutexes.  Instead, threads should
00056 /// use threadsafe collections for all synchronization and communication.
00057 /// This guarantees that a thread will never take two mutexes at once.
00058 ///
00059 /// <b>For now, all code in the AESOP Server should follow this convention and
00060 /// only allow threadsafe collection objects to maintain mutexes.</b>
00061 ///
00062 /// If in the future, data model complexity requires that a thread hold
00063 /// multiple mutexes for some reason, then other solutions could be examined.
00064 /// For the simple data objects used on the server, a hierarchical approach
00065 /// (requiring threads to acquire/release locks in a certain order) may be
00066 /// fine.  But given the realities of how networked games work (dropped
00067 /// UDP packets, network lag leading to clients having to guess at state),
00068 /// the simple approach (never hold multiple locks) should be enough.  In
00069 /// edge cases it can lead to temporary inconsistencies, but the impact
00070 /// should be no worse than a dropped UDP packet.
00071 ///