Ardour  9.0-pre0-582-g084a23a80d
event_loop.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2016 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2015-2017 Robin Gareus <robin@gareus.org>
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 along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #pragma once
21 
22 #include <atomic>
23 #include <string>
24 #include <vector>
25 #include <map>
26 #include <stdint.h>
27 #include <pthread.h>
28 #include <glibmm/threads.h>
29 
30 #include "pbd/libpbd_visibility.h"
31 
32 namespace PBD
33 {
34 
45 {
46 public:
47  EventLoop (std::string const&);
48  virtual ~EventLoop();
49 
50  enum RequestType {
51  range_guarantee = ~0
52  };
53 
54  struct BaseRequestObject;
55 
57  std::list<BaseRequestObject*> requests;
59  std::atomic<int> _valid;
60  std::atomic<int> _ref;
61  const char* file;
62  int line;
63 
64  InvalidationRecord() : event_loop (0), _valid (1), _ref (0) {}
65  void invalidate () { _valid.store (0); }
66  bool valid () { return _valid.load () == 1; }
67 
68  void ref () { _ref.fetch_add (1); }
69  void unref () { (void) _ref.fetch_sub (1); }
70  bool in_use () { return _ref.load () > 0; }
71  int use_count () { return _ref.load (); }
72  };
73 
74  static void* invalidate_request (void* data);
75 
79  std::function<void()> the_slot;
80 
81  BaseRequestObject() : invalidation (0) {}
83  if (invalidation) {
84  invalidation->unref ();
85  }
86  }
87  };
88 
89  virtual bool call_slot (InvalidationRecord*, const std::function<void()>&) = 0;
90  virtual Glib::Threads::RWLock& slot_invalidation_rwlock() = 0;
91 
92  std::string event_loop_name() const { return _name; }
93 
96 
98  pthread_t emitting_thread;
99  size_t num_requests;
100  };
101 
102  static std::vector<ThreadBufferMapping> get_request_buffers_for_target_thread (const std::string&);
103 
104  static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
105  static void remove_request_buffer_from_map (pthread_t);
106 
107  std::list<InvalidationRecord*> trash;
108 
109  static InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
110 
111 private:
112  static Glib::Threads::Private<EventLoop> thread_event_loop;
113  std::string _name;
114 
115  typedef std::vector<ThreadBufferMapping> ThreadRequestBufferList;
117  static Glib::Threads::Mutex thread_buffer_requests_lock;
118 
120 
121  /* @param name : name of object/entity that will/may accept
122  * requests from other threads, via a request buffer.
123  */
124  std::string name;
125 
126  /* @param factory : a function that can be called (with an
127  * argument specifying the @param number_of_requests) to create and
128  * return a request buffer for communicating with @p name)
129  */
130  void* (*factory)(uint32_t nunber_of_requests);
131  };
132  typedef std::vector<RequestBufferSupplier> RequestBufferSuppliers;
134 };
135 
136 }
137 
138 #define MISSING_INVALIDATOR nullptr // used to mark places where we fail to provide an invalidator
139 
EventLoop(std::string const &)
virtual Glib::Threads::RWLock & slot_invalidation_rwlock()=0
std::vector< RequestBufferSupplier > RequestBufferSuppliers
Definition: event_loop.h:132
static void remove_request_buffer_from_map(pthread_t)
virtual ~EventLoop()
static RequestBufferSuppliers request_buffer_suppliers
Definition: event_loop.h:133
std::string event_loop_name() const
Definition: event_loop.h:92
static std::vector< ThreadBufferMapping > get_request_buffers_for_target_thread(const std::string &)
static InvalidationRecord * __invalidator(sigc::trackable &trackable, const char *, int)
virtual bool call_slot(InvalidationRecord *, const std::function< void()> &)=0
std::vector< ThreadBufferMapping > ThreadRequestBufferList
Definition: event_loop.h:115
static Glib::Threads::Mutex thread_buffer_requests_lock
Definition: event_loop.h:117
static void set_event_loop_for_thread(EventLoop *ui)
static void pre_register(const std::string &emitting_thread_name, uint32_t num_requests)
std::list< InvalidationRecord * > trash
Definition: event_loop.h:107
static EventLoop * get_event_loop_for_thread()
static Glib::Threads::Private< EventLoop > thread_event_loop
Definition: event_loop.h:112
static ThreadRequestBufferList thread_buffer_requests
Definition: event_loop.h:116
std::string _name
Definition: event_loop.h:113
static void * invalidate_request(void *data)
#define LIBPBD_API
Definition: axis_view.h:42
InvalidationRecord * invalidation
Definition: event_loop.h:78
std::function< void()> the_slot
Definition: event_loop.h:79
std::list< BaseRequestObject * > requests
Definition: event_loop.h:57