1/* sane - Scanner Access Now Easy.
2   Copyright (C) 1998-2001 Yuri Dario
3   Copyright (C) 2002-2003 Henning Meier-Geinitz (documentation)
4   Copyright (C) 2003-2004 Gerhard Jaeger (pthread/process support)
5   This file is part of the SANE package.
6
7   SANE is free software; you can redistribute it and/or modify it under
8   the terms of the GNU General Public License as published by the Free
9   Software Foundation; either version 2 of the License, or (at your
10   option) any later version.
11
12   SANE is distributed in the hope that it will be useful, but WITHOUT
13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15   for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with sane; see the file COPYING.
19   If not, see <https://www.gnu.org/licenses/>.
20
21   As a special exception, the authors of SANE give permission for
22   additional uses of the libraries contained in this release of SANE.
23
24   The exception is that, if you link a SANE library with other files
25   to produce an executable, this does not by itself cause the
26   resulting executable to be covered by the GNU General Public
27   License.  Your use of that executable is in no way restricted on
28   account of linking the SANE library code into it.
29
30   This exception does not, however, invalidate any other reasons why
31   the executable file might be covered by the GNU General Public
32   License.
33
34   If you submit changes to SANE to the maintainers to be included in
35   a subsequent release, you agree by submitting the changes that
36   those changes may be distributed with this exception intact.
37
38   If you write modifications of your own for SANE, it is your choice
39   whether to permit this exception to apply to your modifications.
40   If you do not wish that, delete this exception notice.
41
42*/
43
44/** @file sanei_thread.h
45 * Support for forking processes and threading.
46 *
47 * Backends should not use fork() directly because fork() does not work
48 * correctly on some platforms. Use the functions provided by sanei_thread
49 * instead. The build system decides if fork() or threads are used.
50 *
51 * Please keep in mind that the behaviour of the child process depends
52 * on if it's a process or thread especially concerning variables.
53 *
54 * In this file we use "task" as an umbrella term for process and thread.
55 *
56 * @sa sanei.h sanei_backend.h
57 */
58
59#ifndef sanei_thread_h
60#define sanei_thread_h
61#include "../include/sane/config.h"
62
63#ifdef USE_PTHREAD
64#include <pthread.h>
65typedef pthread_t SANE_Pid;
66#else
67typedef int SANE_Pid;
68#endif
69
70/** Initialize sanei_thread.
71 *
72 * This function must be called before any other sanei_thread function.
73 */
74extern void sanei_thread_init (void);
75
76/** Do we use processes or threads?
77 *
78 * This function can be used to check if processes or threads are used.
79 *
80 * @return
81 * - SANE_TRUE - if processes are used (fork)
82 * - SANE_FALSE - i threads are used
83 */
84extern SANE_Bool sanei_thread_is_forked (void);
85
86/** Is SANE_Pid valid pid?
87 *
88 * This function can be used to check if thread/fork creation worked
89 * regardless of SANE_Pid's data type.
90 *
91 * @return
92 * - SANE_TRUE - if pid is a valid process
93 * - SANE_FALSE - if pid is not a valid process
94 */
95extern SANE_Bool sanei_thread_is_valid (SANE_Pid pid);
96
97/** Invalidate a SANE_Pid
98 *
99 *  This "function" should be used to invalidate a SANE_Pid in a
100 *  portable manner.
101 *
102 *  @note
103 *  When using pthreads, this only works for those implementations
104 *  that opted to make pthread_t an arithmetic type.  This is *not*
105 *  required by the POSIX threads specification.  The choice to do
106 *  SANE_Pid invalidation by means of a macro rather than a proper
107 *  function circumvents to need to pass a pointer.
108 *  If we decide to implement SANE_Pid with a void* in the future,
109 *  this can be changed into a proper function without the need to
110 *  change existing code.
111 *
112 *  For details on the pthread_t type, see in particular Issue 6 of
113 *  http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html
114 */
115#define sanei_thread_invalidate(pid) ((pid) = (SANE_Pid)(-1))
116
117/** Initialize a SANE_Pid
118 *
119 *  This "function" should be used to initialize a SANE_Pid in a
120 *  portable manner.
121 *
122 *  @note
123 *  This is at present just an alias of sanei_thread_invalidate.
124 *  It seemed misleading to use the latter when intent clearly has
125 *  initialization written all over it, hence the alias.
126 */
127#define sanei_thread_initialize sanei_thread_invalidate
128
129/** Spawn a new task.
130 *
131 * This function should be used to start a new task.
132 *
133 * @param func() function to call as child task
134 * @param args argument of the function (only one!)
135 *
136 * @return
137 * - task id
138 * - -1 if creating the new task failed
139 */
140extern SANE_Pid sanei_thread_begin (int (*func) (void *args), void *args);
141
142/** Terminate spawned task.
143 *
144 * This function terminates the task that was created with sanei_thread_begin.
145 *
146 * For processes, SIGTERM is sent. If threads are used, pthread_cancel()
147 * terminates the task.
148 *
149 * @param pid - the id of the task
150 *
151 * @return
152 * - 0 on success
153 * - any other value if an error occurred while terminating the task
154 */
155extern int sanei_thread_kill (SANE_Pid pid);
156
157/** Send a signal to a task.
158 *
159 * This function can be used to send a signal to a task.
160 *
161 * For terminating the task, sanei_thread_kill() should be used.
162 *
163 * @param pid - the id of the task
164 * @param sig - the signal to send
165 *
166 * @return
167 * - 0 - on success
168 * - any other value - if an error occurred while sending the signal
169 */
170extern int sanei_thread_sendsig (SANE_Pid pid, int sig);
171
172/** Wait for task termination.
173 *
174 * This function waits until a task that has been terminated by
175 * sanei_thread_kill(), sanei_thread_sendsys() or by any other means
176 * is finished.
177 *
178 * @param pid - the id of the task
179 * @param status - status of the task that has just finished
180 *
181 * @return
182 * - the pid of the task we have been waiting for
183 */
184extern SANE_Pid sanei_thread_waitpid (SANE_Pid pid, int *status);
185
186/** Check the current status of the spawned task
187 *
188 *
189 * @param pid - the id of the task
190 *
191 * @return
192 * - SANE_STATUS_GOOD - if the task finished without errors
193 * - any other value - if the task finished unexpectantly or hasn't finished yet
194 */
195extern SANE_Status sanei_thread_get_status (SANE_Pid pid);
196
197#endif /* sanei_thread_h */
198