~ubuntu-branches/ubuntu/trusty/syslog-ng/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/ivykis/modules/iv_thread.c

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS), Gergely Nagy
  • Date: 2011-10-11 14:30:48 UTC
  • mfrom: (1.3.7)
  • Revision ID: package-import@ubuntu.com-20111011143048-r1iljux9xbvj3lwh
Tags: 3.3.1.dfsg-1
* New upstream release with important fixes from upstream git tree with
  non-free manpages removed.
* Drop syslog-ng.conf(5) (closes: #496521).
* syslog-ng(8) is generated, and does not mention -Q anymore
  (closes: #616069).
* Supports CAP_SYSLOG on recent kernels (closes: #630172).
* Does not use g_timeout_add_seconds anymore (closes: #609154).

[ Gergely Nagy <algernon@madhouse-project.org> ]
* Update debian/copyright to DEP-5 format.
* Simplified the logrotate file by merging identical entries.
* Include local configuration files from /etc/syslog-ng/conf.d/ (Closes:
  #609050).
* Update syslog-ng.conf to be fully 3.3 compliant.
* Compress both source and binaries (except the syslog-ng meta
  package) with xz, instead of gzip.
* Use dpkg triggers to restart syslog-ng when appropriate.
* Include DFSG-free manual pages for all binaries.
* Build with Hardening enabled.
* Mention syslog(3) in /etc/default/syslog-ng, instead of
  <linux/kernel.h> (Closes: #608605)
* Support 'status' in the init script.
  Patch from Peter Eisentraut <petere@debian.org> (Closes: #644458)
* Build-Depend on libevtlog-dev (>= 0.2.12-5~) for correct shlibs.
* Use [linux-any] in Build-Depends instead of hardcoded links.
  (Closes: #634715)
* Use $SYSLOGNG_OPTS in the init script when reloading syslog-ng.
  (Closes: #589081)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ivykis, an event handling library
 
3
 * Copyright (C) 2010 Lennert Buytenhek
 
4
 * Dedicated to Marija Kulikova.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU Lesser General Public License version
 
8
 * 2.1 as published by the Free Software Foundation.
 
9
 *
 
10
 * This library 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 Lesser General Public License version 2.1 for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License version 2.1 along with this library; if not, write to the
 
17
 * Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
 
18
 * Boston, MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <iv.h>
 
24
#include <iv_event.h>
 
25
#include <iv_thread.h>
 
26
#include <iv_thr.h>
 
27
#include <string.h>
 
28
 
 
29
/* data structures and global data ******************************************/
 
30
struct iv_thread {
 
31
        struct list_head        list;
 
32
        struct iv_event         dead;
 
33
        char                    *name;
 
34
        pid_t                   tid;
 
35
        void                    (*start_routine)(void *);
 
36
        void                    *arg;
 
37
};
 
38
 
 
39
TLS_BLOCK_START
 
40
{
 
41
        struct list_head child_threads;
 
42
}
 
43
TLS_BLOCK_END;
 
44
 
 
45
#define child_threads __tls_deref(child_threads)
 
46
 
 
47
static int iv_thread_debug;
 
48
 
 
49
 
 
50
/* gettid *******************************************************************/
 
51
#ifdef __FreeBSD__
 
52
/* Older FreeBSDs (6.1) don't include ucontext.h in thr.h.  */
 
53
#include <sys/ucontext.h>
 
54
#include <sys/thr.h>
 
55
#endif
 
56
 
 
57
#ifndef __NR_gettid
 
58
#if defined(linux) && defined(__x86_64__)
 
59
#define __NR_gettid     186
 
60
#elif defined(linux) && defined(__i386__)
 
61
#define __NR_gettid     224
 
62
#endif
 
63
#endif
 
64
 
 
65
static pid_t gettid(void)
 
66
{
 
67
        pid_t tid;
 
68
 
 
69
        tid = 0;
 
70
#ifdef __NR_gettid
 
71
        tid = syscall(__NR_gettid);
 
72
#elif defined(__FreeBSD__)
 
73
        long thr;
 
74
        thr_self(&thr);
 
75
        tid = (pid_t)thr;
 
76
#endif
 
77
 
 
78
        return tid;
 
79
}
 
80
 
 
81
 
 
82
/* callee thread ************************************************************/
 
83
static void iv_thread_cleanup_handler(void *_thr)
 
84
{
 
85
        struct iv_thread *thr = _thr;
 
86
 
 
87
        if (iv_thread_debug)
 
88
                fprintf(stderr, "iv_thread: [%s] was canceled\n", thr->name);
 
89
 
 
90
        iv_event_post(&thr->dead);
 
91
}
 
92
 
 
93
static void *iv_thread_handler(void *_thr)
 
94
{
 
95
        struct iv_thread *thr = _thr;
 
96
 
 
97
        thr->tid = gettid();
 
98
 
 
99
        pthread_cleanup_push(iv_thread_cleanup_handler, thr);
 
100
        thr->start_routine(thr->arg);
 
101
        pthread_cleanup_pop(0);
 
102
 
 
103
        if (iv_thread_debug)
 
104
                fprintf(stderr, "iv_thread: [%s] terminating normally\n",
 
105
                        thr->name);
 
106
 
 
107
        iv_event_post(&thr->dead);
 
108
 
 
109
        return NULL;
 
110
}
 
111
 
 
112
 
 
113
/* calling thread ***********************************************************/
 
114
static void iv_thread_died(void *_thr)
 
115
{
 
116
        struct iv_thread *thr = _thr;
 
117
 
 
118
        if (iv_thread_debug)
 
119
                fprintf(stderr, "iv_thread: [%s] joined\n", thr->name);
 
120
 
 
121
        list_del(&thr->list);
 
122
        iv_event_unregister(&thr->dead);
 
123
        free(thr->name);
 
124
        free(thr);
 
125
}
 
126
 
 
127
int iv_thread_create(char *name, void (*start_routine)(void *), void *arg)
 
128
{
 
129
        struct iv_thread *thr;
 
130
        pthread_attr_t attr;
 
131
        pthread_t t;
 
132
        int ret;
 
133
 
 
134
        thr = malloc(sizeof(*thr));
 
135
        if (thr == NULL)
 
136
                return -1;
 
137
 
 
138
        IV_EVENT_INIT(&thr->dead);
 
139
        thr->dead.cookie = thr;
 
140
        thr->dead.handler = iv_thread_died;
 
141
        iv_event_register(&thr->dead);
 
142
 
 
143
        thr->name = strdup(name);
 
144
        thr->tid = 0;
 
145
        thr->start_routine = start_routine;
 
146
        thr->arg = arg;
 
147
 
 
148
        ret = pthread_attr_init(&attr);
 
149
        if (ret < 0)
 
150
                goto out_event;
 
151
 
 
152
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
153
        if (ret < 0)
 
154
                goto out_attr;
 
155
 
 
156
        ret = pthread_create(&t, &attr, iv_thread_handler, thr);
 
157
        if (ret < 0)
 
158
                goto out_attr;
 
159
 
 
160
        pthread_attr_destroy(&attr);
 
161
 
 
162
        if (child_threads.next == NULL)
 
163
                INIT_LIST_HEAD(&child_threads);
 
164
        list_add_tail(&thr->list, &child_threads);
 
165
 
 
166
        if (iv_thread_debug)
 
167
                fprintf(stderr, "iv_thread: [%s] started\n", name);
 
168
 
 
169
        return 0;
 
170
 
 
171
out_attr:
 
172
        pthread_attr_destroy(&attr);
 
173
 
 
174
out_event:
 
175
        iv_event_unregister(&thr->dead);
 
176
        free(thr);
 
177
 
 
178
        if (iv_thread_debug)
 
179
                fprintf(stderr, "iv_thread: [%s] failed to start\n", name);
 
180
 
 
181
        return -1;
 
182
}
 
183
 
 
184
void iv_thread_set_debug_state(int state)
 
185
{
 
186
        iv_thread_debug = !!state;
 
187
}
 
188
 
 
189
void iv_thread_list_children(void)
 
190
{
 
191
        struct list_head *lh;
 
192
 
 
193
        fprintf(stderr, "tid\tname\n");
 
194
        fprintf(stderr, "%d\tself\n", gettid());
 
195
 
 
196
        list_for_each (lh, &child_threads) {
 
197
                struct iv_thread *thr;
 
198
 
 
199
                thr = list_entry(lh, struct iv_thread, list);
 
200
                fprintf(stderr, "%d\t%s\n", thr->tid, thr->name);
 
201
        }
 
202
}