1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2020 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __AGS_RETURNABLE_THREAD_H__
21 #define __AGS_RETURNABLE_THREAD_H__
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include <ags/thread/ags_thread.h>
27 
28 G_BEGIN_DECLS
29 
30 #define AGS_TYPE_RETURNABLE_THREAD                (ags_returnable_thread_get_type())
31 #define AGS_TYPE_RETURNABLE_THREAD_FLAGS          (ags_returnable_thread_flags_get_type())
32 #define AGS_RETURNABLE_THREAD(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_RETURNABLE_THREAD, AgsReturnableThread))
33 #define AGS_RETURNABLE_THREAD_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST(class, AGS_TYPE_RETURNABLE_THREAD, AgsReturnableThreadClass))
34 #define AGS_IS_RETURNABLE_THREAD(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_RETURNABLE_THREAD))
35 #define AGS_IS_RETURNABLE_THREAD_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_RETURNABLE_THREAD))
36 #define AGS_RETURNABLE_THREAD_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS(obj, AGS_TYPE_RETURNABLE_THREAD, AgsReturnableThreadClass))
37 
38 #define AGS_RETURNABLE_THREAD_DEFAULT_JIFFIE (AGS_THREAD_DEFAULT_MAX_PRECISION)
39 
40 typedef struct _AgsReturnableThread AgsReturnableThread;
41 typedef struct _AgsReturnableThreadClass AgsReturnableThreadClass;
42 
43 typedef void (*AgsReturnableThreadCallback)(AgsReturnableThread *returnable_thread, gpointer data);
44 
45 /**
46  * AgsReturnableThreadFlags:
47  * @AGS_RETURNABLE_THREAD_IN_USE: the thread is in use
48  * @AGS_RETURNABLE_THREAD_RESET: not used
49  * @AGS_RETURNABLE_THREAD_RUN_ONCE: call #AgsThread::run() only one time
50  *
51  * Enum values to control the behavior or indicate internal state of #AgsReturnableThread by
52  * enable/disable as flags.
53  */
54 typedef enum{
55   AGS_RETURNABLE_THREAD_IN_USE              = 1,
56   AGS_RETURNABLE_THREAD_RESET               = 1 << 1,
57   AGS_RETURNABLE_THREAD_RUN_ONCE            = 1 << 2,
58 }AgsReturnableThreadFlags;
59 
60 struct _AgsReturnableThread
61 {
62   AgsThread thread;
63 
64   volatile guint flags;
65 
66   GObject *thread_pool;
67 
68   GRecMutex reset_mutex;
69   volatile void *safe_data;
70 
71   gulong handler;
72 };
73 
74 struct _AgsReturnableThreadClass
75 {
76   AgsThreadClass thread;
77 
78   void (*safe_run)(AgsReturnableThread *returnable_thread);
79 };
80 
81 GType ags_returnable_thread_get_type();
82 GType ags_returnable_thread_flags_get_type();
83 
84 gboolean ags_returnable_thread_test_flags(AgsReturnableThread *returnable_thread, guint flags);
85 void ags_returnable_thread_set_flags(AgsReturnableThread *returnable_thread, guint flags);
86 void ags_returnable_thread_unset_flags(AgsReturnableThread *returnable_thread, guint flags);
87 
88 void ags_returnable_thread_safe_run(AgsReturnableThread *returnable_thread);
89 
90 void ags_returnable_thread_connect_safe_run(AgsReturnableThread *returnable_thread, AgsReturnableThreadCallback callback);
91 void ags_returnable_thread_disconnect_safe_run(AgsReturnableThread *returnable_thread);
92 
93 AgsReturnableThread* ags_returnable_thread_new(GObject *thread_pool);
94 
95 G_END_DECLS
96 
97 #endif /*__AGS_RETURNABLE_THREAD_H__*/
98