summaryrefslogtreecommitdiff
path: root/libs/vdr/include/Thread.h
blob: ce8c99946cdc0bcf17b88719de8616c614fe5c21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
 * File:      Thread.h
 * Project:   libvdr - classes taken from vdr-project
 * 
 * from "Video Disk Recorder":
 * 
 * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * The original author can be reached at kls@tvdr.de
 * 
 * The vdr project's page is at http://www.tvdr.de
 * 
 * ++2012-07-04(rma):
 * As I don't like the necessity to subclass what should work in a thread,
 * I extended the original sources, so that an arbitrary function can be
 * a thread kernel.
 */
#ifndef THREAD_H
#define	THREAD_H

#include <Mutex.h>
#include <stddef.h>
#include <pthread.h>
typedef pid_t tThreadId;

class cThread {
public:
  cThread(const char *Description = NULL);
       ///< Creates a new thread.
       ///< If Description is present, a log file entry will be made when
       ///< the thread starts and stops. The Start() function must be called
       ///< to actually start the thread.
  cThread(int (*ThreadCallback)(void *opaque, cThread *instance), void *opaque, const char *Description = NULL);
  virtual ~cThread();

  void SetDescription(const char *Description, ...) __attribute__ ((format (printf, 2, 3)));
  bool Start(void);
       ///< Actually starts the thread.
       ///< If the thread is already running, nothing happens.
  virtual void Cancel(int WaitSeconds = 0);
       ///< Cancels the thread by first setting 'running' to false, so that
       ///< the Action() loop can finish in an orderly fashion and then waiting
       ///< up to WaitSeconds seconds for the thread to actually end. If the
       ///< thread doesn't end by itself, it is killed.
       ///< If WaitSeconds is -1, only 'running' is set to false and Cancel()
       ///< returns immediately, without killing the thread.
  bool Active(void);
       ///< used from outside to check whether the thread is still alive.
  bool Running(void) { return running; }
       ///< used from inside the thread to check whether it may keep on running.
       ///< Returns false if a derived cThread object shall leave its Action()
       ///< function. Should be public and so available for callback thread kernels

  static tThreadId ThreadId(void);
  static tThreadId IsMainThread(void) { return ThreadId() == mainThreadId; }
  static void SetMainThreadId(void);

protected:
  void SetPriority(int Priority);
  void SetIOPriority(int Priority);
  void Lock(void) { mutex.Lock(); }
  void Unlock(void) { mutex.Unlock(); }
  virtual void Action(void);
       ///< A derived cThread class must implement the code it wants to
       ///< execute as a separate thread in this function. If this is
       ///< a loop, it must check Running() repeatedly to see whether
       ///< it's time to stop.
       ///< To support callbacks as thread kernels, default implementation now
       ///< starts the callback

private:
  bool active;
  bool running;
  pthread_t childTid;
  tThreadId childThreadId;
  cMutex mutex;
  char *description;
  int (*threadCallback)(void *, cThread *);
  void *opaque;
  static tThreadId mainThreadId;
  static void *StartThread(cThread *Thread);
  friend class cThreadLock;
  };

#endif	/* THREAD_H */