1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gnome-vfs-job-slave.c - Thread for asynchronous GnomeVFSJobs
3 (version for POSIX threads).
5 Copyright (C) 1999 Free Software Foundation
7 The Gnome Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 The Gnome 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 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with the Gnome Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Author: Ettore Perazzoli <ettore@comm2000.it> */
25 #include "gnome-vfs-job-slave.h"
27 #include "gnome-vfs-async-job-map.h"
28 #include "gnome-vfs-thread-pool.h"
29 #include "gnome-vfs-job-queue.h"
30 #include <glib/gmessages.h>
33 static volatile gboolean gnome_vfs_quitting = FALSE;
34 static volatile gboolean gnome_vfs_done_quitting = FALSE;
38 thread_routine (void *data)
42 GnomeVFSAsyncHandle *job_handle;
45 job_handle = (GnomeVFSAsyncHandle *) data;
47 id = GPOINTER_TO_UINT (job_handle);
48 /* job map must always be locked before the job_lock
49 * if both locks are needed */
50 _gnome_vfs_async_job_map_lock ();
52 job = _gnome_vfs_async_job_map_get_job (job_handle);
55 JOB_DEBUG (("job already dead, bail %u", id));
56 _gnome_vfs_async_job_map_unlock ();
60 JOB_DEBUG (("locking job_lock %u", id));
61 g_mutex_lock (job->job_lock);
62 _gnome_vfs_async_job_map_unlock ();
64 _gnome_vfs_job_execute (job);
65 complete = _gnome_vfs_job_complete (job);
67 JOB_DEBUG (("Unlocking access lock %u", id));
68 g_mutex_unlock (job->job_lock);
71 _gnome_vfs_async_job_map_lock ();
72 JOB_DEBUG (("job %u done, removing from map and destroying", id));
73 _gnome_vfs_async_job_completed (job_handle);
74 _gnome_vfs_job_destroy (job);
75 _gnome_vfs_async_job_map_unlock ();
82 _gnome_vfs_job_create_slave (GnomeVFSJob *job)
84 g_return_val_if_fail (job != NULL, FALSE);
86 if (gnome_vfs_quitting) {
87 g_warning ("Someone still starting up GnomeVFS async calls after quit.");
90 if (gnome_vfs_done_quitting) {
91 /* The application is quitting, we have already returned from
92 * gnome_vfs_wait_for_slave_threads, we can't start any more threads
93 * because they would potentially block indefinitely and prevent the
99 if (_gnome_vfs_thread_create (thread_routine, job->job_handle) != 0) {
100 g_warning ("Impossible to allocate a new GnomeVFSJob thread.");
102 /* thread did not start up, remove the job from the hash table */
103 _gnome_vfs_async_job_completed (job->job_handle);
104 _gnome_vfs_job_destroy (job);
112 _gnome_vfs_thread_backend_shutdown (void)
119 gnome_vfs_quitting = TRUE;
121 JOB_DEBUG (("###### shutting down"));
123 _gnome_vfs_job_queue_shutdown();
125 for (count = 0; ; count++) {
126 /* Check if it is OK to quit. Originally we used a
127 * count of slave threads, but now we use a count of
128 * outstanding jobs instead to make sure that the job
129 * is cleanly destroyed.
131 if (gnome_vfs_job_get_count () == 0) {
133 gnome_vfs_done_quitting = TRUE;
140 /* Some threads are still trying to quit, wait a bit until they
143 g_main_context_iteration (NULL, FALSE);
147 _gnome_vfs_thread_pool_shutdown ();
148 _gnome_vfs_async_job_map_shutdown ();