LCOV - code coverage report
Current view: top level - snapwebsites - snap_communicator.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 43 0.0 %
Date: 2019-12-15 17:13:15 Functions: 0 72 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Snap Communicator -- classes to ease handling communication between processes
       2             : 
       3             : // Copyright (c) 2012-2019  Made to Order Software Corp.  All Rights Reserved
       4             : //
       5             : // This program is free software; you can redistribute it and/or modify
       6             : // it under the terms of the GNU General Public License as published by
       7             : // the Free Software Foundation; either version 2 of the License, or
       8             : // (at your option) any later version.
       9             : //
      10             : // This program is distributed in the hope that it will be useful,
      11             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : // GNU General Public License for more details.
      14             : //
      15             : // You should have received a copy of the GNU General Public License
      16             : // along with this program; if not, write to the Free Software
      17             : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      18             : #pragma once
      19             : 
      20             : // self
      21             : //
      22             : #include "snapwebsites/snap_exception.h"
      23             : #include "snapwebsites/snap_thread.h"
      24             : #include "snapwebsites/tcp_client_server.h"
      25             : #include "snapwebsites/udp_client_server.h"
      26             : //#include "snapwebsites/log.h" -- not sensible here at this time because log.h includes snap_communicator.h -- See Jira SNAP-623
      27             : #include "snapwebsites/snap_string_list.h"
      28             : 
      29             : // snapdev lib
      30             : //
      31             : #include <snapdev/not_used.h>
      32             : 
      33             : // Qt lib
      34             : //
      35             : #pragma GCC diagnostic push
      36             : #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
      37             : #include <QMap>
      38             : #pragma GCC diagnostic pop
      39             : 
      40             : // C lib
      41             : //
      42             : #include <signal.h>
      43             : #include <sys/signalfd.h>
      44             : 
      45             : 
      46             : namespace snap
      47             : {
      48             : 
      49           0 : class snap_communicator_parameter_error : public snap_logic_exception
      50             : {
      51             : public:
      52           0 :     snap_communicator_parameter_error(char const *        what_msg) : snap_logic_exception("snap_communicator", what_msg) {}
      53           0 :     snap_communicator_parameter_error(std::string const & what_msg) : snap_logic_exception("snap_communicator", what_msg) {}
      54           0 :     snap_communicator_parameter_error(QString const &     what_msg) : snap_logic_exception("snap_communicator", what_msg) {}
      55             : };
      56             : 
      57           0 : class snap_communicator_implementation_error : public snap_logic_exception
      58             : {
      59             : public:
      60           0 :     snap_communicator_implementation_error(char const *        what_msg) : snap_logic_exception("snap_communicator", what_msg) {}
      61             :     snap_communicator_implementation_error(std::string const & what_msg) : snap_logic_exception("snap_communicator", what_msg) {}
      62           0 :     snap_communicator_implementation_error(QString const &     what_msg) : snap_logic_exception("snap_communicator", what_msg) {}
      63             : };
      64             : 
      65           0 : class snap_communicator_exception : public snap_exception
      66             : {
      67             : public:
      68           0 :     explicit snap_communicator_exception(char const *        what_msg) : snap_exception("snap_communicator", what_msg) {}
      69           0 :     explicit snap_communicator_exception(std::string const & what_msg) : snap_exception("snap_communicator", what_msg) {}
      70           0 :     explicit snap_communicator_exception(QString const &     what_msg) : snap_exception("snap_communicator", what_msg) {}
      71             : };
      72             : 
      73           0 : class snap_communicator_initialization_error : public snap_communicator_exception
      74             : {
      75             : public:
      76           0 :     snap_communicator_initialization_error(char const *        what_msg) : snap_communicator_exception(what_msg) {}
      77             :     snap_communicator_initialization_error(std::string const & what_msg) : snap_communicator_exception(what_msg) {}
      78             :     snap_communicator_initialization_error(QString const &     what_msg) : snap_communicator_exception(what_msg) {}
      79             : };
      80             : 
      81           0 : class snap_communicator_runtime_error : public snap_communicator_exception
      82             : {
      83             : public:
      84           0 :     snap_communicator_runtime_error(char const *        what_msg) : snap_communicator_exception(what_msg) {}
      85           0 :     snap_communicator_runtime_error(std::string const & what_msg) : snap_communicator_exception(what_msg) {}
      86           0 :     snap_communicator_runtime_error(QString const &     what_msg) : snap_communicator_exception(what_msg) {}
      87             : };
      88             : 
      89           0 : class snap_communicator_unexpected_data : public snap_communicator_exception
      90             : {
      91             : public:
      92           0 :     snap_communicator_unexpected_data(char const *        what_msg) : snap_communicator_exception(what_msg) {}
      93             :     snap_communicator_unexpected_data(std::string const & what_msg) : snap_communicator_exception(what_msg) {}
      94             :     snap_communicator_unexpected_data(QString const &     what_msg) : snap_communicator_exception(what_msg) {}
      95             : };
      96             : 
      97           0 : class snap_communicator_invalid_message : public snap_communicator_exception
      98             : {
      99             : public:
     100           0 :     snap_communicator_invalid_message(char const *        what_msg) : snap_communicator_exception(what_msg) {}
     101             :     snap_communicator_invalid_message(std::string const & what_msg) : snap_communicator_exception(what_msg) {}
     102           0 :     snap_communicator_invalid_message(QString const &     what_msg) : snap_communicator_exception(what_msg) {}
     103             : };
     104             : 
     105             : 
     106             : 
     107           0 : class snap_communicator_message
     108             : {
     109             : public:
     110             :     typedef QMap<QString, QString>                  parameters_t;
     111             :     typedef std::vector<snap_communicator_message>  vector_t;
     112             : 
     113             :     bool                    from_message(QString const & message);
     114             :     QString                 to_message() const;
     115             : 
     116             :     QString const &         get_sent_from_server() const;
     117             :     void                    set_sent_from_server(QString const & server);
     118             :     QString const &         get_sent_from_service() const;
     119             :     void                    set_sent_from_service(QString const & service);
     120             :     QString const &         get_server() const;
     121             :     void                    set_server(QString const & server);
     122             :     QString const &         get_service() const;
     123             :     void                    set_service(QString const & service);
     124             :     void                    reply_to(snap_communicator_message const & message);
     125             :     QString const &         get_command() const;
     126             :     void                    set_command(QString const & command);
     127             :     void                    add_parameter(QString const & name, char const * value);
     128             :     void                    add_parameter(QString const & name, std::string const & value);
     129             :     void                    add_parameter(QString const & name, QString const & value);
     130             :     void                    add_parameter(QString const & name, int32_t value);
     131             :     void                    add_parameter(QString const & name, uint32_t value);
     132             :     void                    add_parameter(QString const & name, int64_t value);
     133             :     void                    add_parameter(QString const & name, uint64_t value);
     134             :     bool                    has_parameter(QString const & name) const;
     135             :     QString const           get_parameter(QString const & name) const;
     136             :     int64_t                 get_integer_parameter(QString const & name) const;
     137             :     parameters_t const &    get_all_parameters() const;
     138             : 
     139             :     static void             verify_name(QString const & name, bool can_be_empty = false, bool can_be_lowercase = true);
     140             : 
     141             : private:
     142             :     QString                 f_sent_from_server = QString();
     143             :     QString                 f_sent_from_service = QString();
     144             :     QString                 f_server = QString();
     145             :     QString                 f_service = QString();
     146             :     QString                 f_command = QString();
     147             :     parameters_t            f_parameters = parameters_t();
     148             :     mutable QString         f_cached_message = QString();
     149             : };
     150             : 
     151             : 
     152             : 
     153           0 : class dispatcher_base
     154             : {
     155             : public:
     156             :     typedef std::shared_ptr<dispatcher_base>    pointer_t;
     157             :     typedef std::weak_ptr<dispatcher_base>      weak_t;
     158             : 
     159             :     virtual                 ~dispatcher_base();
     160             : 
     161             :     virtual bool            get_commands(snap_string_list & commands) = 0;
     162             :     virtual bool            dispatch(snap::snap_communicator_message & msg) = 0;
     163             : 
     164             : private:
     165             : };
     166             : 
     167             : 
     168             : 
     169             : 
     170             : 
     171             : 
     172             : 
     173             : // forward class declaration
     174             : class snap_tcp_client_permanent_message_connection_impl;
     175             : 
     176             : 
     177             : 
     178             : // WARNING: a snap_communicator object must be allocated and held in a shared pointer (see pointer_t)
     179             : #pragma GCC diagnostic push
     180             : #pragma GCC diagnostic ignored "-Weffc++"
     181             : #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
     182           0 : class snap_communicator
     183             :     : public std::enable_shared_from_this<snap_communicator>
     184             : {
     185             : public:
     186             :     typedef std::shared_ptr<snap_communicator>      pointer_t;
     187             : 
     188             :     // this version defines the protocol version, it should really rarely
     189             :     // change if ever
     190             :     static int const                                VERSION = 1;
     191             : 
     192             :     typedef int                                     priority_t;
     193             : 
     194             :     static priority_t const                         EVENT_MAX_PRIORITY = 255;
     195             : 
     196           0 :     class snap_dispatcher_support
     197             :     {
     198             :     public:
     199             :         virtual                     ~snap_dispatcher_support();
     200             : 
     201             :         void                        set_dispatcher(dispatcher_base::pointer_t d);
     202             :         dispatcher_base::pointer_t  get_dispatcher() const;
     203             :         bool                        dispatch_message(snap::snap_communicator_message & msg);
     204             : 
     205             :         // new callback
     206             :         virtual void                process_message(snap_communicator_message const & message);
     207             : 
     208             :     private:
     209             :         dispatcher_base::weak_t     f_dispatcher = dispatcher_base::weak_t();
     210             :     };
     211             : 
     212             :     class snap_connection
     213             :         : public std::enable_shared_from_this<snap_connection>
     214             :     {
     215             :     public:
     216             :         typedef std::shared_ptr<snap_connection>    pointer_t;
     217             :         typedef std::vector<pointer_t>              vector_t;
     218             : 
     219             :                                     snap_connection();
     220             : 
     221             :         // prevent copies
     222             :                                     snap_connection(snap_connection const & connection) = delete;
     223             :         snap_connection &           operator = (snap_connection const & connection) = delete;
     224             : 
     225             :         // virtual classes must have a virtual destructor
     226             :         virtual                     ~snap_connection();
     227             : 
     228             :         void                        remove_from_communicator();
     229             : 
     230             :         QString const &             get_name() const;
     231             :         void                        set_name(QString const & name);
     232             : 
     233             :         virtual bool                is_listener() const;
     234             :         virtual bool                is_signal() const;
     235             :         virtual bool                is_reader() const;
     236             :         virtual bool                is_writer() const;
     237             :         virtual int                 get_socket() const = 0;
     238             :         virtual bool                valid_socket() const;
     239             : 
     240             :         bool                        is_enabled() const;
     241             :         virtual void                set_enable(bool enabled);
     242             : 
     243             :         int                         get_priority() const;
     244             :         void                        set_priority(priority_t priority);
     245             :         static bool                 compare(pointer_t const & lhs, pointer_t const & rhs);
     246             : 
     247             :         uint16_t                    get_event_limit() const;
     248             :         void                        set_event_limit(uint16_t event_limit);
     249             :         uint16_t                    get_processing_time_limit() const;
     250             :         void                        set_processing_time_limit(int32_t processing_time_limit);
     251             : 
     252             :         int64_t                     get_timeout_delay() const;
     253             :         void                        set_timeout_delay(int64_t timeout_us);
     254             :         void                        calculate_next_tick();
     255             :         int64_t                     get_timeout_date() const;
     256             :         void                        set_timeout_date(int64_t date_us);
     257             :         int64_t                     get_timeout_timestamp() const;
     258             : 
     259             :         void                        non_blocking() const;
     260             :         void                        keep_alive() const;
     261             : 
     262             :         bool                        is_done() const;
     263             :         void                        mark_done();
     264             :         void                        mark_not_done();
     265             : 
     266             :         // callbacks
     267             :         virtual void                process_timeout();
     268             :         virtual void                process_signal();
     269             :         virtual void                process_read();
     270             :         virtual void                process_write();
     271             :         virtual void                process_empty_buffer();
     272             :         virtual void                process_accept();
     273             :         virtual void                process_error();
     274             :         virtual void                process_hup();
     275             :         virtual void                process_invalid();
     276             :         virtual void                connection_added();
     277             :         virtual void                connection_removed();
     278             : 
     279             :     private:
     280             :         friend snap_communicator;
     281             : 
     282             :         int64_t                     save_timeout_timestamp();
     283             :         int64_t                     get_saved_timeout_timestamp() const;
     284             : 
     285             :         QString                     f_name = QString();
     286             :         bool                        f_enabled = true;
     287             :         bool                        f_done = false;
     288             :         uint16_t                    f_event_limit = 5;                  // limit before giving other events a chance
     289             :         priority_t                  f_priority = 100;
     290             :         int64_t                     f_timeout_delay = -1;               // in microseconds
     291             :         int64_t                     f_timeout_next_date = -1;           // in microseconds, when we use the f_timeout_delay
     292             :         int64_t                     f_timeout_date = -1;                // in microseconds
     293             :         int64_t                     f_saved_timeout_stamp = -1;         // in microseconds
     294             :         int32_t                     f_processing_time_limit = 500000;   // in microseconds
     295             :         int                         f_fds_position = -1;
     296             :     };
     297             : 
     298           0 :     class connection_with_send_message
     299             :     {
     300             :     public:
     301             :         virtual                     ~connection_with_send_message();
     302             : 
     303             :         // new callback
     304             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) = 0;
     305             : 
     306             :         virtual void                msg_help(snap_communicator_message & message);
     307             :         virtual void                msg_alive(snap_communicator_message & message);
     308             :         virtual void                msg_log(snap_communicator_message & message);
     309             :         virtual void                msg_quitting(snap_communicator_message & message);
     310             :         virtual void                msg_ready(snap_communicator_message & message);
     311             :         virtual void                msg_stop(snap_communicator_message & message);
     312             :         virtual void                msg_log_unknown(snap_communicator_message & message);
     313             :         virtual void                msg_reply_with_unknown(snap_communicator_message & message);
     314             : 
     315             :         virtual void                help(snap_string_list & commands);
     316             :         virtual void                ready(snap_communicator_message & message);
     317             :         virtual void                stop(bool quitting);
     318             :     };
     319             : 
     320           0 :     class snap_timer
     321             :         : public snap_connection
     322             :     {
     323             :     public:
     324             :         // timer is implemented using the timeout value on poll().
     325             :         // we could have another implementation that makes use of
     326             :         // the timerfd_create() function (in which case we'd be
     327             :         // limited to a date timeout, although an interval would
     328             :         // work too but require a little bit of work.)
     329             :         //
     330             :         typedef std::shared_ptr<snap_timer>    pointer_t;
     331             : 
     332             :                                     snap_timer(int64_t timeout_us);
     333             : 
     334             :         // snap_connection implementation
     335             :         virtual int                 get_socket() const override;
     336             :         virtual bool                valid_socket() const override;
     337             :     };
     338             : 
     339             :     class snap_signal
     340             :         : public snap_connection
     341             :     {
     342             :     public:
     343             :         typedef std::shared_ptr<snap_signal>    pointer_t;
     344             : 
     345             :                                     snap_signal(int posix_signal);
     346             :         virtual                     ~snap_signal() override;
     347             : 
     348             :         void                        close();
     349             :         void                        unblock_signal_on_destruction();
     350             : 
     351             :         // snap_connection implementation
     352             :         virtual bool                is_signal() const override;
     353             :         virtual int                 get_socket() const override;
     354             : 
     355             :         pid_t                       get_child_pid() const;
     356             : 
     357             :     private:
     358             :         friend snap_communicator;
     359             : 
     360             :         void                        process();
     361             : 
     362             :         int                         f_signal = 0;   // i.e. SIGHUP, SIGTERM...
     363             :         int                         f_socket = -1;  // output of signalfd()
     364             :         struct signalfd_siginfo     f_signal_info = signalfd_siginfo();
     365             :         bool                        f_unblock = false;
     366             :     };
     367             : 
     368             :     class snap_thread_done_signal
     369             :         : public snap_connection
     370             :     {
     371             :     public:
     372             :         typedef std::shared_ptr<snap_thread_done_signal>    pointer_t;
     373             : 
     374             :                                     snap_thread_done_signal();
     375             :         virtual                     ~snap_thread_done_signal() override;
     376             : 
     377             :         // snap_connection implementation
     378             :         virtual bool                is_reader() const override;
     379             :         virtual int                 get_socket() const override;
     380             :         virtual void                process_read() override;
     381             : 
     382             :         void                        thread_done();
     383             : 
     384             :     private:
     385             :         int                         f_pipe[2] = { -1, -1 };      // pipes
     386             :     };
     387             : 
     388             :     class snap_inter_thread_message_connection
     389             :         : public snap_connection
     390             :         , public connection_with_send_message
     391             :     {
     392             :     public:
     393             :         typedef std::shared_ptr<snap_inter_thread_message_connection>    pointer_t;
     394             : 
     395             :                                     snap_inter_thread_message_connection();
     396             :         virtual                     ~snap_inter_thread_message_connection() override;
     397             : 
     398             :         void                        close();
     399             : 
     400             :         // the child cannot have its own snap_communicator object, so...
     401             :         int                         poll(int timeout);
     402             : 
     403             :         // snap_connection implementation
     404             :         virtual bool                is_reader() const override;
     405             :         //virtual bool                is_writer() const override;
     406             :         virtual int                 get_socket() const override;
     407             :         virtual void                process_read() override;
     408             : 
     409             :         // connection_with_send_message
     410             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) override;
     411             : 
     412             :         // new callback
     413             :         virtual void                process_message_a(snap_communicator_message const & message) = 0;
     414             :         virtual void                process_message_b(snap_communicator_message const & message) = 0;
     415             : 
     416             :     private:
     417             :         pid_t                       f_creator_id = -1;
     418             : 
     419             :         std::shared_ptr<int>        f_thread_a = std::shared_ptr<int>();
     420             :         snap::snap_thread::snap_fifo<snap_communicator_message>
     421             :                                     f_message_a = snap::snap_thread::snap_fifo<snap_communicator_message>();
     422             : 
     423             :         std::shared_ptr<int>        f_thread_b = std::shared_ptr<int>();
     424             :         snap::snap_thread::snap_fifo<snap_communicator_message>
     425             :                                     f_message_b = snap::snap_thread::snap_fifo<snap_communicator_message>();
     426             :     };
     427             : 
     428             :     class snap_pipe_connection
     429             :         : public snap_connection
     430             :     {
     431             :     public:
     432             :         typedef std::shared_ptr<snap_pipe_connection>    pointer_t;
     433             : 
     434             :                                     snap_pipe_connection();
     435             :         virtual                     ~snap_pipe_connection() override;
     436             : 
     437             :         void                        close();
     438             : 
     439             :         // snap_connection implementation
     440             :         virtual bool                is_reader() const override;
     441             :         virtual int                 get_socket() const override;
     442             : 
     443             :         // new callbacks
     444             :         virtual ssize_t             read(void * buf, size_t count);
     445             :         virtual ssize_t             write(void const * buf, size_t count);
     446             : 
     447             :     private:
     448             :         pid_t                       f_parent = -1;  // the process that created these pipes (read/write to 0 if getpid() == f_parent, read/write to 1 if getpid() != f_parent)
     449             :         int                         f_socket[2] = { -1, -1 };    // socket pair
     450             :     };
     451             : 
     452           0 :     class snap_pipe_buffer_connection
     453             :         : public snap_pipe_connection
     454             :     {
     455             :     public:
     456             :         typedef std::shared_ptr<snap_pipe_buffer_connection>    pointer_t;
     457             : 
     458             :         // snap::snap_communicator::snap_connection
     459             :         virtual bool                is_writer() const override;
     460             : 
     461             :         // snap::snap_communicator::snap_pipe_connection implementation
     462             :         virtual ssize_t             write(void const * data, size_t length) override;
     463             :         virtual void                process_read() override;
     464             :         virtual void                process_write() override;
     465             :         virtual void                process_hup() override;
     466             : 
     467             :         // new callback
     468             :         virtual void                process_line(QString const & line) = 0;
     469             : 
     470             :     private:
     471             :         std::string                 f_line = std::string(); // do NOT use QString because UTF-8 would break often... (since we may only receive part of messages)
     472             :         std::vector<char>           f_output = std::vector<char>();
     473             :         size_t                      f_position = 0;
     474             :     };
     475             : 
     476           0 :     class snap_pipe_message_connection
     477             :         : public snap_pipe_buffer_connection
     478             :         , public snap_dispatcher_support
     479             :         , public connection_with_send_message
     480             :     {
     481             :     public:
     482             :         typedef std::shared_ptr<snap_pipe_message_connection>    pointer_t;
     483             : 
     484             :         // connection_with_send_message
     485             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) override;
     486             : 
     487             :         // snap_tcp_server_client_buffer_connection implementation
     488             :         virtual void                process_line(QString const & line) override;
     489             :     };
     490             : 
     491             :     class snap_file_changed
     492             :         : public snap_connection
     493             :     {
     494             :     public:
     495             :         typedef std::shared_ptr<snap_file_changed>      pointer_t;
     496             :         typedef uint32_t                                event_mask_t;
     497             : 
     498             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_NO_EVENTS  = 0x0000;
     499             : 
     500             :         // bits added to watch_...() functions
     501             :         //
     502             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_ATTRIBUTES = 0x0001;   // chmod, chown (timestamp, link count, user/group, etc.)
     503             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_READ       = 0x0002;   // read, execve
     504             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_WRITE      = 0x0004;   // write, truncate
     505             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_CREATED    = 0x0008;   // open & O_CREAT, rename, mkdir, link, symlink, bind
     506             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_DELETED    = 0x0010;   // unlink, rename
     507             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_ACCESS     = 0x0020;   // open, close
     508             : 
     509             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_IO         = SNAP_FILE_CHANGED_EVENT_READ
     510             :                                                                        | SNAP_FILE_CHANGED_EVENT_WRITE;
     511             : 
     512             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_ALL        = SNAP_FILE_CHANGED_EVENT_ATTRIBUTES
     513             :                                                                        | SNAP_FILE_CHANGED_EVENT_IO
     514             :                                                                        | SNAP_FILE_CHANGED_EVENT_CREATED
     515             :                                                                        | SNAP_FILE_CHANGED_EVENT_DELETED
     516             :                                                                        | SNAP_FILE_CHANGED_EVENT_ACCESS;
     517             : 
     518             :         // flags added in event_t objects
     519             :         //
     520             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_DIRECTORY  = 0x1000;   // object is a directory
     521             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_GONE       = 0x2000;   // removed
     522             :         static event_mask_t const   SNAP_FILE_CHANGED_EVENT_UNMOUNTED  = 0x4000;   // unmounted
     523             : 
     524           0 :         class event_t
     525             :         {
     526             :         public:
     527             :                                     event_t(std::string const & watched_path
     528             :                                           , event_mask_t events
     529             :                                           , std::string const & filename);
     530             : 
     531             :             std::string const &     get_watched_path() const;
     532             :             event_mask_t            get_events() const;
     533             :             std::string const &     get_filename() const;
     534             : 
     535             :             bool                    operator < (event_t const & rhs) const;
     536             : 
     537             :         private:
     538             :             std::string             f_watched_path = std::string();
     539             :             event_mask_t            f_events       = 0;
     540             :             std::string             f_filename     = std::string();
     541             :         };
     542             : 
     543             :                                     snap_file_changed();
     544             :         virtual                     ~snap_file_changed() override;
     545             : 
     546             :         void                        watch_file(std::string const & watched_path, event_mask_t const events);
     547             :         void                        watch_symlink(std::string const & watched_path, event_mask_t const events);
     548             :         void                        watch_directory(std::string const & watched_path, event_mask_t const events);
     549             : 
     550             :         void                        stop_watch(std::string const & watched_path);
     551             : 
     552             :         // snap_connection implementation
     553             :         virtual bool                is_reader() const override;
     554             :         virtual int                 get_socket() const override;
     555             :         virtual void                set_enable(bool enabled);
     556             :         virtual void                process_read() override;
     557             : 
     558             :         // new callback
     559             :         virtual void                process_event(event_t const & watch_event) = 0;
     560             : 
     561             :     private:
     562             :         // TODO: RAII would be great with an impl and a counter...
     563             :         //       (i.e. we make copies at the moment.)
     564           0 :         struct watch_t
     565             :         {
     566             :             typedef std::map<int, watch_t>          map_t;
     567             : 
     568             :                                     watch_t();
     569             :                                     watch_t(std::string const & watched_path, event_mask_t events, uint32_t add_flags);
     570             : 
     571             :             void                    add_watch(int inotify);
     572             :             void                    merge_watch(int inotify, event_mask_t const events);
     573             :             void                    remove_watch(int inotify);
     574             : 
     575             :             std::string             f_watched_path = std::string();
     576             :             event_mask_t            f_events       = SNAP_FILE_CHANGED_EVENT_NO_EVENTS;
     577             :             uint32_t                f_mask         = 0;
     578             :             int                     f_watch        = -1;
     579             :         };
     580             : 
     581             :         bool                        merge_watch(std::string const & watched_path, event_mask_t const events);
     582             :         static uint32_t             events_to_mask(event_mask_t const events);
     583             :         static event_mask_t         mask_to_events(uint32_t const mask);
     584             : 
     585             :         int                         f_inotify = -1;
     586             :         watch_t::map_t              f_watches = watch_t::map_t();
     587             :     };
     588             : 
     589           0 :     class snap_fd_connection
     590             :         : public snap_connection
     591             :     {
     592             :     public:
     593             :         typedef std::shared_ptr<snap_fd_connection>         pointer_t;
     594             : 
     595             :         enum class mode_t
     596             :         {
     597             :             FD_MODE_READ,
     598             :             FD_MODE_WRITE,
     599             :             FD_MODE_RW
     600             :         };
     601             : 
     602             :                                     snap_fd_connection(int fd, mode_t mode);
     603             : 
     604             :         void                        close();
     605             :         void                        mark_closed();
     606             : 
     607             :         // snap_connection implementation
     608             :         virtual bool                is_reader() const override;
     609             :         virtual bool                is_writer() const override;
     610             :         virtual int                 get_socket() const override;
     611             : 
     612             :         // new callbacks
     613             :         virtual ssize_t             read(void * buf, size_t count);
     614             :         virtual ssize_t             write(void const * buf, size_t count);
     615             : 
     616             :     private:
     617             :         int                         f_fd = -1;
     618             :         mode_t                      f_mode = mode_t::FD_MODE_RW;
     619             :     };
     620             : 
     621           0 :     class snap_fd_buffer_connection
     622             :         : public snap_fd_connection
     623             :     {
     624             :     public:
     625             :         typedef std::shared_ptr<snap_fd_buffer_connection>    pointer_t;
     626             : 
     627             :                                     snap_fd_buffer_connection(int fd, mode_t mode);
     628             : 
     629             :         bool                        has_input() const;
     630             :         bool                        has_output() const;
     631             :         virtual bool                is_writer() const override;
     632             : 
     633             :         // snap_fd_connection implementation
     634             :         virtual ssize_t             write(void const * data, size_t const length) override;
     635             : 
     636             :         // snap_connection implementation
     637             :         virtual void                process_read() override;
     638             :         virtual void                process_write() override;
     639             :         virtual void                process_hup() override;
     640             : 
     641             :         // new callback
     642             :         virtual void                process_line(QString const & line) = 0;
     643             : 
     644             :     private:
     645             :         std::string                 f_line = std::string(); // input -- do NOT use QString because UTF-8 would break often... (since we may only receive part of messages)
     646             :         std::vector<char>           f_output = std::vector<char>();
     647             :         size_t                      f_position = 0;
     648             :     };
     649             : 
     650           0 :     class snap_tcp_client_connection
     651             :         : public snap_connection
     652             :         , public tcp_client_server::bio_client
     653             :     {
     654             :     public:
     655             :         typedef std::shared_ptr<snap_tcp_client_connection>    pointer_t;
     656             : 
     657             :                                     snap_tcp_client_connection(std::string const & addr, int port, mode_t mode = mode_t::MODE_PLAIN);
     658             : 
     659             :         QString const &             get_remote_address() const;
     660             : 
     661             :         // snap_connection implementation
     662             :         virtual bool                is_reader() const override;
     663             :         virtual int                 get_socket() const override;
     664             : 
     665             :         // new callbacks
     666             :         virtual ssize_t             read(void * buf, size_t count);
     667             :         virtual ssize_t             write(void const * buf, size_t count);
     668             : 
     669             :     private:
     670             :         QString const               f_remote_address = QString();
     671             :     };
     672             : 
     673           0 :     class snap_tcp_server_connection
     674             :         : public snap_connection
     675             :         , public tcp_client_server::bio_server
     676             :     {
     677             :     public:
     678             :         typedef std::shared_ptr<snap_tcp_server_connection>    pointer_t;
     679             : 
     680             :                                     snap_tcp_server_connection(std::string const & addr, int port, std::string const & certificate, std::string const & private_key, mode_t mode = mode_t::MODE_PLAIN, int max_connections = -1, bool reuse_addr = false);
     681             : 
     682             :         // snap_connection implementation
     683             :         virtual bool                is_listener() const override;
     684             :         virtual int                 get_socket() const override;
     685             :     };
     686             : 
     687             :     class snap_tcp_server_client_connection
     688             :         : public snap_connection
     689             :         //, public tcp_client_server::tcp_client -- this will not work without some serious re-engineering of the tcp_client class
     690             :     {
     691             :     public:
     692             :         typedef std::shared_ptr<snap_tcp_server_client_connection>    pointer_t;
     693             : 
     694             :                                     snap_tcp_server_client_connection(tcp_client_server::bio_client::pointer_t client);
     695             :         virtual                     ~snap_tcp_server_client_connection() override;
     696             : 
     697             :         void                        close();
     698             :         size_t                      get_client_address(struct sockaddr_storage & address) const;
     699             :         std::string                 get_client_addr() const;
     700             :         int                         get_client_port() const;
     701             :         std::string                 get_client_addr_port() const;
     702             : 
     703             :         // snap_connection implementation
     704             :         virtual bool                is_reader() const override;
     705             :         virtual int                 get_socket() const override;
     706             : 
     707             :         // new callbacks
     708             :         virtual ssize_t             read(void * buf, size_t count);
     709             :         virtual ssize_t             write(void const * buf, size_t count);
     710             : 
     711             :     private:
     712             :         bool                        define_address();
     713             : 
     714             :         tcp_client_server::bio_client::pointer_t
     715             :                                     f_client = tcp_client_server::bio_client::pointer_t();
     716             :         struct sockaddr_storage     f_address = sockaddr_storage();
     717             :         socklen_t                   f_length = 0;
     718             :     };
     719             : 
     720           0 :     class snap_tcp_server_client_buffer_connection
     721             :         : public snap_tcp_server_client_connection
     722             :     {
     723             :     public:
     724             :         typedef std::shared_ptr<snap_tcp_server_client_buffer_connection>    pointer_t;
     725             : 
     726             :                                     snap_tcp_server_client_buffer_connection(tcp_client_server::bio_client::pointer_t client);
     727             : 
     728             :         bool                        has_input() const;
     729             :         bool                        has_output() const;
     730             : 
     731             :         // snap::snap_communicator::snap_connection
     732             :         virtual bool                is_writer() const override;
     733             : 
     734             :         // snap::snap_communicator::snap_tcp_server_client_connection implementation
     735             :         virtual ssize_t             write(void const * data, size_t const length) override;
     736             :         virtual void                process_read() override;
     737             :         virtual void                process_write() override;
     738             :         virtual void                process_hup() override;
     739             : 
     740             :         // new callback
     741             :         virtual void                process_line(QString const & line) = 0;
     742             : 
     743             :     private:
     744             :         std::string                 f_line = std::string(); // input -- do NOT use QString because UTF-8 would break often... (since we may only receive part of messages)
     745             :         std::vector<char>           f_output = std::vector<char>();
     746             :         size_t                      f_position = 0;
     747             :     };
     748             : 
     749           0 :     class snap_tcp_server_client_message_connection
     750             :         : public snap_tcp_server_client_buffer_connection
     751             :         , public snap_dispatcher_support
     752             :         , public connection_with_send_message
     753             :     {
     754             :     public:
     755             :         typedef std::shared_ptr<snap_tcp_server_client_message_connection>    pointer_t;
     756             : 
     757             :                                     snap_tcp_server_client_message_connection(tcp_client_server::bio_client::pointer_t client);
     758             : 
     759             :         QString const &             get_remote_address() const;
     760             : 
     761             :         // connection_with_send_message
     762             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) override;
     763             : 
     764             :         // snap_tcp_server_client_buffer_connection implementation
     765             :         virtual void                process_line(QString const & line) override;
     766             : 
     767             :     private:
     768             :         QString                     f_remote_address = QString();
     769             :     };
     770             : 
     771           0 :     class snap_tcp_client_buffer_connection
     772             :         : public snap_tcp_client_connection
     773             :     {
     774             :     public:
     775             :         typedef std::shared_ptr<snap_tcp_client_buffer_connection>    pointer_t;
     776             : 
     777             :                                     snap_tcp_client_buffer_connection(std::string const & addr, int port, mode_t const mode = mode_t::MODE_PLAIN, bool const blocking = false);
     778             : 
     779             :         bool                        has_input() const;
     780             :         bool                        has_output() const;
     781             : 
     782             :         // snap::snap_communicator::snap_tcp_client_connection implementation
     783             :         virtual ssize_t             write(void const * data, size_t length) override;
     784             :         virtual bool                is_writer() const override;
     785             :         virtual void                process_read() override;
     786             :         virtual void                process_write() override;
     787             :         virtual void                process_hup() override;
     788             : 
     789             :         // new callback
     790             :         virtual void                process_line(QString const & line) = 0;
     791             : 
     792             :     private:
     793             :         std::string                 f_line = std::string(); // input -- do NOT use QString because UTF-8 would break often... (since we may only receive part of messages)
     794             :         std::vector<char>           f_output = std::vector<char>();
     795             :         size_t                      f_position = 0;
     796             :     };
     797             : 
     798           0 :     class snap_tcp_client_message_connection
     799             :         : public snap_tcp_client_buffer_connection
     800             :         , public snap_dispatcher_support
     801             :         , public connection_with_send_message
     802             :     {
     803             :     public:
     804             :         typedef std::shared_ptr<snap_tcp_client_message_connection>    pointer_t;
     805             : 
     806             :                                     snap_tcp_client_message_connection(std::string const & addr, int port, mode_t const mode = mode_t::MODE_PLAIN, bool const blocking = false);
     807             : 
     808             :         // connection_with_send_message
     809             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) override;
     810             : 
     811             :         // snap_tcp_client_reader_connection implementation
     812             :         virtual void                process_line(QString const & line) override;
     813             :     };
     814             : 
     815             :     class snap_tcp_client_permanent_message_connection
     816             :         : public snap_timer
     817             :         , public snap_dispatcher_support
     818             :         , public connection_with_send_message
     819             :     {
     820             :     public:
     821             :         typedef std::shared_ptr<snap_tcp_client_permanent_message_connection>    pointer_t;
     822             : 
     823             :         static int64_t const        DEFAULT_PAUSE_BEFORE_RECONNECTING = 60LL * 1000000LL;  // 1 minute
     824             : 
     825             :                                     snap_tcp_client_permanent_message_connection(std::string const & address, int port, tcp_client_server::bio_client::mode_t mode = tcp_client_server::bio_client::mode_t::MODE_PLAIN, int64_t const pause = DEFAULT_PAUSE_BEFORE_RECONNECTING, bool const use_thread = true);
     826             :         virtual                     ~snap_tcp_client_permanent_message_connection() override;
     827             : 
     828             :         bool                        is_connected() const;
     829             :         void                        disconnect();
     830             :         void                        mark_done();
     831             :         void                        mark_done(bool messenger);
     832             :         size_t                      get_client_address(struct sockaddr_storage & address) const;
     833             :         std::string                 get_client_addr() const;
     834             : 
     835             :         // connection_with_send_message
     836             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) override;
     837             : 
     838             :         // snap_connection implementation
     839             :         virtual void                process_timeout() override;
     840             :         virtual void                process_error() override;
     841             :         virtual void                process_hup() override;
     842             :         virtual void                process_invalid() override;
     843             :         virtual void                connection_removed() override;
     844             : 
     845             :         // new callbacks
     846             :         virtual void                process_connection_failed(std::string const & error_message);
     847             :         virtual void                process_connected();
     848             : 
     849             :     private:
     850             :         std::shared_ptr<snap_tcp_client_permanent_message_connection_impl>
     851             :                                     f_impl = std::shared_ptr<snap_tcp_client_permanent_message_connection_impl>();
     852             :         int64_t                     f_pause = 0;
     853             :         bool const                  f_use_thread = true;
     854             :     };
     855             : 
     856           0 :     class snap_udp_server_connection
     857             :         : public snap_connection
     858             :         , public udp_client_server::udp_server
     859             :     {
     860             :     public:
     861             :         typedef std::shared_ptr<snap_udp_server_connection>    pointer_t;
     862             : 
     863             :                                     snap_udp_server_connection(std::string const & addr, int port);
     864             : 
     865             :         // snap_connection implementation
     866             :         virtual bool                is_reader() const override;
     867             :         virtual int                 get_socket() const override;
     868             : 
     869             :         void                        set_secret_code(std::string const & secret_code);
     870             :         std::string const &         get_secret_code() const;
     871             : 
     872             :     private:
     873             :         std::string                 f_secret_code = std::string();
     874             :     };
     875             : 
     876           0 :     class snap_udp_server_message_connection
     877             :         : public snap_udp_server_connection
     878             :         , public snap_dispatcher_support
     879             :     {
     880             :     public:
     881             :         typedef std::shared_ptr<snap_udp_server_message_connection>    pointer_t;
     882             : 
     883             :         static size_t const         DATAGRAM_MAX_SIZE = 1024;
     884             : 
     885             :                                     snap_udp_server_message_connection(std::string const & addr, int port);
     886             : 
     887             :         static bool                 send_message(std::string const & addr
     888             :                                                , int port
     889             :                                                , snap_communicator_message const & message
     890             :                                                , std::string const & secret_code = std::string());
     891             : 
     892             :         // snap_connection implementation
     893             :         virtual void                process_read() override;
     894             : 
     895             :     private:
     896             :     };
     897             : 
     898           0 :     class snap_tcp_blocking_client_message_connection
     899             :         : public snap_tcp_client_message_connection
     900             :     {
     901             :     public:
     902             :                                     snap_tcp_blocking_client_message_connection(std::string const & addr, int port, mode_t mode = mode_t::MODE_PLAIN);
     903             : 
     904             :         void                        run();
     905             :         void                        peek();
     906             : 
     907             :         // connection_with_send_message
     908             :         virtual bool                send_message(snap_communicator_message const & message, bool cache = false) override;
     909             : 
     910             :         // snap_connection callback
     911             :         virtual void                process_error() override;
     912             : 
     913             :     private:
     914             :         std::string                 f_line = std::string();
     915             :     };
     916             : 
     917             :     static pointer_t                    instance();
     918             : 
     919             :     // prevent copies
     920             :                                         snap_communicator(snap_communicator const & communicator) = delete;
     921             :     snap_communicator &                 operator = (snap_communicator const & communicator) = delete;
     922             : 
     923             :     snap_connection::vector_t const &   get_connections() const;
     924             :     bool                                add_connection(snap_connection::pointer_t connection);
     925             :     bool                                remove_connection(snap_connection::pointer_t connection);
     926             :     virtual bool                        run();
     927             : 
     928             :     static int64_t                      get_current_date();
     929             : 
     930             : private:
     931             :                                         snap_communicator();
     932             : 
     933             :     snap_connection::vector_t           f_connections = snap_connection::vector_t();
     934             :     bool                                f_force_sort = true;
     935             : };
     936             : #pragma GCC diagnostic pop
     937             : 
     938             : 
     939             : } // namespace snap
     940             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13