~ubuntu-branches/ubuntu/natty/libvirt/natty-security

« back to all changes in this revision

Viewing changes to src/util/threadpool.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-02-23 09:05:46 UTC
  • mfrom: (1.2.8 upstream) (3.4.25 sid)
  • Revision ID: james.westby@ubuntu.com-20110223090546-4pwmrrt7h51hr3l3
Tags: 0.8.8-1ubuntu1
* Resynchronize and merge from Debian unstable. Remaining changes:
  - debian/patches:
    * 9000-delayed_iff_up_bridge.patch
    * 9001-dont_clobber_existing_bridges.patch
    * 9002-better_default_uri_virsh.patch
    * 9003-better-default-arch.patch
    * 9004-libvirtd-group-name.patch
    * 9005-increase-unix-socket-timeout.patch
    * 9006-default-config-test-case.patch
    * 9007-fix-daemon-conf-ftbfs.patch
    * 9011-move-ebtables-script.patch
    * 9014-skip-nodeinfotest.patch
    * 9020-lp545795.patch
    * 9021-fix-uint64_t.patch
  - debian/patches/series:
    * Disable qemu-disable-network.diff.patch
  - debian/control:
    * set ubuntu maintainer
    * Build-Depends:
      - swap libxen to libxen3, qemu to qemu-kvm, and open-iscsi to
        open-iscsi-utils in Build-Depends
      - remove virtualbox Build-Depends
      - add libxml2 and libapparmor-dev Build-Depends
    * convert Vcs-Git to Xs-Debian-Vcs-Git
    * libvirt-bin Depends: move netcat-openbsd, bridge-utils, dnsmasq-base
      (>= 2.46-1), and iptables from Recommends to Depends
    * libvirt-bin Recommends: move qemu to Suggests
    * libvirt-bin Suggests: add apparmor
    * libvirt0 Recommands: move lvm2 to Suggests
  - keep debian/libvirt-bin.apport
  - keep debian/libvirt-bin.cron.daily
  - debian/libvirt-bin.dirs:
    * add apparmor, cron.daily, and apport dirs
  - debian/libvirt-bin.examples:
    * add debian/libvirt-suspendonreboot
  - debian/libvirt-bin.install:
    * add /etc/apparmor.d files
    * add apport hook
  - debian/libvirt-bin.manpages:
    * add debian/libvirt-migrate-qemu-disks.1
  - debian/libvirt-bin.postinst:
    * replace libvirt groupname with libvirtd
    * add each admin user to libvirtd group
    * call apparmor_parser on usr.sbin.libvirtd and
      usr.lib.libvirt.virt-aa-helper
    * call 'libvirt-migrate-qemu-disks -a' after
      libvirt-bin has started if migrating from
      older than 0.8.3-1ubuntu1
  - debian/libvirt-bin.postrm:
    * replace libvirt groupname with libvirtd
    * remove usr.sbin.libvirtd and
      usr.lib.libvirt.virt-aa-helper
  - keep added files under debian/:
    * libvirt-bin.upstart
    * libvirt-migrate-qemu-disks
    * libvirt-migrate-qemu-disks.1
    * libvirt-suspendonreboot
    * apparmor profiles
  - debian/README.Debian:
    * add 'Apparmor Profile' section
    * add 'Disk migration' section
  - debian/rules:
    * don't build with vbox since virtualbox-ose is in universe
    * add --with-apparmor to DEB_CONFIGURE_EXTRA_FLAGS
    * set DEB_DH_INSTALLINIT_ARGS to '--upstart-only'
    * set DEB_MAKE_CHECK_TARGET to 'check'
    * remove unneeded binary-install/libvirt-bin:: and clean::
      sections (they only deal with sysvinit stuff)
    * add build/libvirt-bin:: section to install
      - apparmor files
      - apport hooks
      - libvirt-migrate-qemu-disks
* The following Ubuntu packaging changes occurred during the divergence
  between Debian and Ubuntu. These changes are not new, but included here
  for completeness: (0.8.5-0ubuntu1 - 0.8.5-0ubuntu5):
  - Have upstart job source /etc/default/libvirt-bin.  This is only a
    temporary fix until upstart provides proper default override support
    through /etc/init/libvirt-bin.override (or any other mechanism).
    (LP: 708172)
  - debian/apparmor/usr.sbin.libvirtd: use PUx instead of Ux for executables
    (LP: 573315)
  - Rebuild with python 2.7 as the python default.
  - debian/libvirt-bin.cron.daily: use shell globbing to enumerate xml files.
    Based on patch thanks to Henryk Plötz (LP: 655176)
* Dropped the following patches included/fixed upstream:
  - 9010-dont-disable-ipv6.patch
  - 9022-build-cleanup-declaration-of-xen-tests.patch
  - 9023-vah-require-uuid.patch
  - 9009-autodetect-nc-params.patch
    * rolled into Debian's
      Autodetect-if-the-remote-nc-command-supports-the-q-o.patch
* Updated the following patches:
  - 9011-move-ebtables-script.patch:
    * LOCALSTATEDIR is defined in configmake.h
  - 9000-9006: added DEP-3 tags
  - 9002-better_default_uri_virsh.patch: updated (context changed)
* New patches:
  - 9022-drop-booton-when-kernel-specified.patch (LP: #720426)
  - 9023-fix-lxc-console-hangup.patch (LP: #668369)
  - 9024-skip-broken-commandtest.patch
* debian/patches/series:
  - don't apply Disable-CHECKSUM-rule.patch: our iptables can do this
  - don't apply Debian-specific Debianize-libvirt-guests.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * threadpool.c: a generic thread pool implementation
 
3
 *
 
4
 * Copyright (C) 2010 Hu Tao
 
5
 * Copyright (C) 2010 Daniel P. Berrange
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
20
 *
 
21
 * Authors:
 
22
 *     Hu Tao <hutao@cn.fujitsu.com>
 
23
 *     Daniel P. Berrange <berrange@redhat.com>
 
24
 */
 
25
 
 
26
#include <config.h>
 
27
 
 
28
#include <stdbool.h>
 
29
 
 
30
#include "threadpool.h"
 
31
#include "memory.h"
 
32
#include "threads.h"
 
33
#include "virterror_internal.h"
 
34
#include "ignore-value.h"
 
35
 
 
36
#define VIR_FROM_THIS VIR_FROM_NONE
 
37
 
 
38
typedef struct _virThreadPoolJob virThreadPoolJob;
 
39
typedef virThreadPoolJob *virThreadPoolJobPtr;
 
40
 
 
41
struct _virThreadPoolJob {
 
42
    virThreadPoolJobPtr next;
 
43
 
 
44
    void *data;
 
45
};
 
46
 
 
47
typedef struct _virThreadPoolJobList virThreadPoolJobList;
 
48
typedef virThreadPoolJobList *virThreadPoolJobListPtr;
 
49
 
 
50
struct _virThreadPoolJobList {
 
51
    virThreadPoolJobPtr head;
 
52
    virThreadPoolJobPtr *tail;
 
53
};
 
54
 
 
55
 
 
56
struct _virThreadPool {
 
57
    bool quit;
 
58
 
 
59
    virThreadPoolJobFunc jobFunc;
 
60
    void *jobOpaque;
 
61
    virThreadPoolJobList jobList;
 
62
 
 
63
    virMutex mutex;
 
64
    virCond cond;
 
65
    virCond quit_cond;
 
66
 
 
67
    size_t maxWorkers;
 
68
    size_t freeWorkers;
 
69
    size_t nWorkers;
 
70
    virThreadPtr workers;
 
71
};
 
72
 
 
73
static void virThreadPoolWorker(void *opaque)
 
74
{
 
75
    virThreadPoolPtr pool = opaque;
 
76
 
 
77
    virMutexLock(&pool->mutex);
 
78
 
 
79
    while (1) {
 
80
        while (!pool->quit &&
 
81
               !pool->jobList.head) {
 
82
            pool->freeWorkers++;
 
83
            if (virCondWait(&pool->cond, &pool->mutex) < 0) {
 
84
                pool->freeWorkers--;
 
85
                goto out;
 
86
            }
 
87
            pool->freeWorkers--;
 
88
        }
 
89
 
 
90
        if (pool->quit)
 
91
            break;
 
92
 
 
93
        virThreadPoolJobPtr job = pool->jobList.head;
 
94
        pool->jobList.head = pool->jobList.head->next;
 
95
        job->next = NULL;
 
96
        if (pool->jobList.tail == &job->next)
 
97
            pool->jobList.tail = &pool->jobList.head;
 
98
 
 
99
        virMutexUnlock(&pool->mutex);
 
100
        (pool->jobFunc)(job->data, pool->jobOpaque);
 
101
        VIR_FREE(job);
 
102
        virMutexLock(&pool->mutex);
 
103
    }
 
104
 
 
105
out:
 
106
    pool->nWorkers--;
 
107
    if (pool->nWorkers == 0)
 
108
        virCondSignal(&pool->quit_cond);
 
109
    virMutexUnlock(&pool->mutex);
 
110
}
 
111
 
 
112
virThreadPoolPtr virThreadPoolNew(size_t minWorkers,
 
113
                                  size_t maxWorkers,
 
114
                                  virThreadPoolJobFunc func,
 
115
                                  void *opaque)
 
116
{
 
117
    virThreadPoolPtr pool;
 
118
    size_t i;
 
119
 
 
120
    if (minWorkers > maxWorkers)
 
121
        minWorkers = maxWorkers;
 
122
 
 
123
    if (VIR_ALLOC(pool) < 0) {
 
124
        virReportOOMError();
 
125
        return NULL;
 
126
    }
 
127
 
 
128
    pool->jobList.head = NULL;
 
129
    pool->jobList.tail = &pool->jobList.head;
 
130
 
 
131
    pool->jobFunc = func;
 
132
    pool->jobOpaque = opaque;
 
133
 
 
134
    if (virMutexInit(&pool->mutex) < 0)
 
135
        goto error;
 
136
    if (virCondInit(&pool->cond) < 0)
 
137
        goto error;
 
138
    if (virCondInit(&pool->quit_cond) < 0)
 
139
        goto error;
 
140
 
 
141
    if (VIR_ALLOC_N(pool->workers, minWorkers) < 0)
 
142
        goto error;
 
143
 
 
144
    pool->maxWorkers = maxWorkers;
 
145
    for (i = 0; i < minWorkers; i++) {
 
146
        if (virThreadCreate(&pool->workers[i],
 
147
                            true,
 
148
                            virThreadPoolWorker,
 
149
                            pool) < 0) {
 
150
            goto error;
 
151
        }
 
152
        pool->nWorkers++;
 
153
    }
 
154
 
 
155
    return pool;
 
156
 
 
157
error:
 
158
    virThreadPoolFree(pool);
 
159
    return NULL;
 
160
 
 
161
}
 
162
 
 
163
void virThreadPoolFree(virThreadPoolPtr pool)
 
164
{
 
165
    virThreadPoolJobPtr job;
 
166
 
 
167
    if (!pool)
 
168
        return;
 
169
 
 
170
    virMutexLock(&pool->mutex);
 
171
    pool->quit = true;
 
172
    if (pool->nWorkers > 0) {
 
173
        virCondBroadcast(&pool->cond);
 
174
        ignore_value(virCondWait(&pool->quit_cond, &pool->mutex));
 
175
    }
 
176
 
 
177
    while ((job = pool->jobList.head)) {
 
178
        pool->jobList.head = pool->jobList.head->next;
 
179
        VIR_FREE(job);
 
180
    }
 
181
 
 
182
    VIR_FREE(pool->workers);
 
183
    virMutexUnlock(&pool->mutex);
 
184
    virMutexDestroy(&pool->mutex);
 
185
    ignore_value(virCondDestroy(&pool->quit_cond));
 
186
    ignore_value(virCondDestroy(&pool->cond));
 
187
    VIR_FREE(pool);
 
188
}
 
189
 
 
190
int virThreadPoolSendJob(virThreadPoolPtr pool,
 
191
                         void *jobData)
 
192
{
 
193
    virThreadPoolJobPtr job;
 
194
 
 
195
    virMutexLock(&pool->mutex);
 
196
    if (pool->quit)
 
197
        goto error;
 
198
 
 
199
    if (pool->freeWorkers == 0 &&
 
200
        pool->nWorkers < pool->maxWorkers) {
 
201
        if (VIR_EXPAND_N(pool->workers, pool->nWorkers, 1) < 0) {
 
202
            virReportOOMError();
 
203
            goto error;
 
204
        }
 
205
 
 
206
        if (virThreadCreate(&pool->workers[pool->nWorkers - 1],
 
207
                            true,
 
208
                            virThreadPoolWorker,
 
209
                            pool) < 0) {
 
210
            pool->nWorkers--;
 
211
            goto error;
 
212
        }
 
213
    }
 
214
 
 
215
    if (VIR_ALLOC(job) < 0) {
 
216
        virReportOOMError();
 
217
        goto error;
 
218
    }
 
219
 
 
220
    job->data = jobData;
 
221
    job->next = NULL;
 
222
    *pool->jobList.tail = job;
 
223
    pool->jobList.tail = &(*pool->jobList.tail)->next;
 
224
 
 
225
    virCondSignal(&pool->cond);
 
226
    virMutexUnlock(&pool->mutex);
 
227
 
 
228
    return 0;
 
229
 
 
230
error:
 
231
    virMutexUnlock(&pool->mutex);
 
232
    return -1;
 
233
}