Ardour  9.2-70-g6916ee188f
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 <sigc++/trackable.h>
23 #include <sigc++/connection.h>
24 
25 #include <atomic>
26 #include <functional>
27 #include <string>
28 #include <list>
29 #include <vector>
30 #include <stdint.h>
31 #include <pthread.h>
32 
33 #include "pbd/libpbd_visibility.h"
34 #include "pbd/mutex.h"
35 #include "pbd/private.h"
36 #include "pbd/rwlock.h"
37 
38 namespace PBD
39 {
40 
51 {
52 public:
53  EventLoop (std::string const&);
54  virtual ~EventLoop();
55 
56  enum RequestType {
57  range_guarantee = ~0
58  };
59 
60  struct BaseRequestObject;
61 
63  std::list<BaseRequestObject*> requests;
65  std::atomic<int> _valid;
66  std::atomic<int> _ref;
67  const char* file;
68  int line;
69 
70  InvalidationRecord() : event_loop (0), _valid (1), _ref (0) {}
71  void invalidate () { _valid.store (0); }
72  bool valid () { return _valid.load () == 1; }
73 
74  void ref () { _ref.fetch_add (1); }
75  void unref () { (void) _ref.fetch_sub (1); }
76  bool in_use () { return _ref.load () > 0; }
77  int use_count () { return _ref.load (); }
78  };
79 
80  static void* invalidate_request (void* data);
81 
85  std::function<void()> the_slot;
86 
87  BaseRequestObject() : invalidation (0) {}
89  if (invalidation) {
90  invalidation->unref ();
91  }
92  }
93  };
94 
95  virtual bool call_slot (InvalidationRecord*, const std::function<void()>&) = 0;
97 
98  std::string event_loop_name() const { return _name; }
99 
102 
104  pthread_t emitting_thread;
105  size_t num_requests;
106  };
107 
108  static std::vector<ThreadBufferMapping> get_request_buffers_for_target_thread (const std::string&);
109 
110  static void pre_register (const std::string& emitting_thread_name, uint32_t num_requests);
111  static void remove_request_buffer_from_map (pthread_t);
112 
113  std::list<InvalidationRecord*> trash;
114 
115  static InvalidationRecord* __invalidator (sigc::trackable& trackable, const char*, int);
116 
117 private:
119  std::string _name;
120 
121  typedef std::vector<ThreadBufferMapping> ThreadRequestBufferList;
124 
126 
127  /* @param name : name of object/entity that will/may accept
128  * requests from other threads, via a request buffer.
129  */
130  std::string name;
131 
132  /* @param factory : a function that can be called (with an
133  * argument specifying the @param number_of_requests) to create and
134  * return a request buffer for communicating with @p name)
135  */
136  void* (*factory)(uint32_t nunber_of_requests);
137  };
138  typedef std::vector<RequestBufferSupplier> RequestBufferSuppliers;
140 };
141 
142 }
143 
144 #define MISSING_INVALIDATOR nullptr // used to mark places where we fail to provide an invalidator
145 
EventLoop(std::string const &)
std::vector< RequestBufferSupplier > RequestBufferSuppliers
Definition: event_loop.h:138
static PBD::Mutex thread_buffer_requests_lock
Definition: event_loop.h:123
static void remove_request_buffer_from_map(pthread_t)
virtual ~EventLoop()
static RequestBufferSuppliers request_buffer_suppliers
Definition: event_loop.h:139
std::string event_loop_name() const
Definition: event_loop.h:98
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:121
static void set_event_loop_for_thread(EventLoop *ui)
static void pre_register(const std::string &emitting_thread_name, uint32_t num_requests)
virtual PBD::RWLock & slot_invalidation_rwlock()=0
std::list< InvalidationRecord * > trash
Definition: event_loop.h:113
static EventLoop * get_event_loop_for_thread()
static ThreadRequestBufferList thread_buffer_requests
Definition: event_loop.h:122
std::string _name
Definition: event_loop.h:119
static PBD::Private< EventLoop > thread_event_loop
Definition: event_loop.h:118
static void * invalidate_request(void *data)
#define LIBPBD_API
Definition: axis_view.h:42
InvalidationRecord * invalidation
Definition: event_loop.h:84
std::function< void()> the_slot
Definition: event_loop.h:85
std::list< BaseRequestObject * > requests
Definition: event_loop.h:63