Experimental patch to ensure playback buffer bounds use minimal beat->frame rounding.
[ardour.git] / libs / ardour / ardour / worker.h
1 /*
2   Copyright (C) 2012 Paul Davis
3   Author: David Robillard
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #ifndef __ardour_worker_h__
21 #define __ardour_worker_h__
22
23 #include <stdint.h>
24
25 #include <glibmm/threads.h>
26
27 #include "pbd/ringbuffer.h"
28 #include "pbd/semutils.h"
29
30 #include "ardour/libardour_visibility.h"
31
32 namespace ARDOUR {
33
34 /**
35    An object that needs to schedule non-RT work in the audio thread.
36 */
37 class LIBARDOUR_API Workee {
38 public:
39         virtual ~Workee() {}
40
41         /**
42            Do some work in the worker thread.
43         */
44         virtual int work(uint32_t size, const void* data) = 0;
45
46         /**
47            Handle a response from the worker thread in the audio thread.
48         */
49         virtual int work_response(uint32_t size, const void* data) = 0;
50 };
51
52 /**
53    A worker thread for non-realtime tasks scheduled in the audio thread.
54 */
55 class LIBARDOUR_API Worker
56 {
57 public:
58         Worker(Workee* workee, uint32_t ring_size);
59         ~Worker();
60
61         /**
62            Schedule work (audio thread).
63            @return false on error.
64         */
65         bool schedule(uint32_t size, const void* data);
66
67         /**
68            Respond from work (worker thread).
69            @return false on error.
70         */
71         bool respond(uint32_t size, const void* data);
72
73         /**
74            Emit any pending responses (audio thread).
75         */
76         void emit_responses();
77
78 private:
79         void run();
80         /**
81            Peek in RB, get size and check if a block of 'size' is available.
82
83            Handle the unlikley edge-case, if we're called in between the
84            responder writing 'size' and 'data'.
85
86                  @param rb the ringbuffer to check
87                  @return true if the message is complete, false otherwise
88          */
89         bool verify_message_completeness(RingBuffer<uint8_t>* rb);
90
91         Workee*                _workee;
92         RingBuffer<uint8_t>*   _requests;
93         RingBuffer<uint8_t>*   _responses;
94         uint8_t*               _response;
95         PBD::Semaphore  _sem;
96         bool                   _exit;
97         Glib::Threads::Thread* _thread;
98
99 };
100
101 } // namespace ARDOUR
102
103 #endif  /* __ardour_worker_h__ */