LogCabin
Event/Signal.h
Go to the documentation of this file.
00001 /* Copyright (c) 2011-2014 Stanford University
00002  * Copyright (c) 2015 Diego Ongaro
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 #ifndef LOGCABIN_EVENT_SIGNAL_H
00018 #define LOGCABIN_EVENT_SIGNAL_H
00019 
00020 #include "Event/File.h"
00021 
00022 namespace LogCabin {
00023 namespace Event {
00024 
00025 // forward declaration
00026 class Loop;
00027 
00028 /**
00029  * A Signal is called by the Event::Loop when a Unix signal is received.
00030  * The client should inherit from this and implement the handleSignalEvent()
00031  * method for when the signal is received. This is persistent; it will handle
00032  * repeated delivery of the signal.
00033  *
00034  * Signal handlers can be created from any thread, but they will always fire on
00035  * the thread running the Event::Loop.
00036  */
00037 class Signal : private Event::File {
00038   public:
00039     /**
00040      * Blocks asynchronous signal delivery on the current thread for the given
00041      * signal. This should normally be called before any secondary threads are
00042      * started, so that all subsequent threads also have the signal blocked.
00043      * \warning
00044      *      This class is not thread-safe: the caller must use an external
00045      *      mutex or (more commonly) may only manipulate this class while
00046      *      a single thread is running.
00047      */
00048     class Blocker {
00049       public:
00050         /**
00051          * Constructor.
00052          * Masks asynchronous signal delivery for signalNumber.
00053          */
00054         explicit Blocker(int signalNumber);
00055         /**
00056          * Destructor. Unmasks asynchronous signal delivery for signalNumber.
00057          */
00058         ~Blocker();
00059         /**
00060          * Blocks further signals if they are not already blocked.
00061          */
00062         void block();
00063         /**
00064          * Leave the signal blocked when this object is destroyed.
00065          */
00066         void leaveBlocked();
00067         /**
00068          * Unblocks signals if they are blocked. Also clears
00069          * #shouldLeaveBlocked.
00070          */
00071         void unblock();
00072         const int signalNumber;
00073       private:
00074         /**
00075          * Set to true if the signal is currently blocked.
00076          */
00077         bool isBlocked;
00078         /**
00079          * Set to true if the signal should be left unblocked on destruction.
00080          */
00081         bool shouldLeaveBlocked;
00082     };
00083 
00084     /**
00085      * Registers a Signal handler to be monitored by the Event::Loop. Once this
00086      * is constructed, the Event::Loop will call the Signal's event handler
00087      * appropriately.
00088      *
00089      * This object must be destroyed or disableForever() called BEFORE the
00090      * Signal object can be destroyed safely.
00091      */
00092     class Monitor : private File::Monitor {
00093       public:
00094         /// See File::Monitor::Monitor.
00095         Monitor(Event::Loop& eventLoop, Signal& signal);
00096         /// See File::Monitor::~Monitor.
00097         ~Monitor();
00098         /// See File::Monitor::disableForever.
00099         using File::Monitor::disableForever;
00100     };
00101 
00102     /**
00103      * Construct a signal handler.
00104      * See also Blocker, which you'll generally need to create first,
00105      * and Monitor, which you'll need to create after.
00106      * \param signalNumber
00107      *      The signal number identifying which signal to receive
00108      *      (man signal.h).
00109      */
00110     explicit Signal(int signalNumber);
00111 
00112     /**
00113      * Destructor.
00114      */
00115     virtual ~Signal();
00116 
00117     /**
00118      * This method is overridden by a subclass and invoked when the signal
00119      * is received. This method will be invoked by the main event loop on
00120      * whatever thread is running the Event::Loop.
00121      */
00122     virtual void handleSignalEvent() = 0;
00123 
00124     /**
00125      * The signal number identifying which signal to receive (man signal.h).
00126      */
00127     const int signalNumber;
00128 
00129   private:
00130     /**
00131      * Generic event handler for files. Calls handleSignalEvent().
00132      */
00133     void handleFileEvent(uint32_t events);
00134 
00135     // Signal is not copyable.
00136     Signal(const Signal&) = delete;
00137     Signal& operator=(const Signal&) = delete;
00138 };
00139 
00140 } // namespace LogCabin::Event
00141 } // namespace LogCabin
00142 
00143 #endif /* LOGCABIN_EVENT_SIGNAL_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines