1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* Copyright (C) 2003, 2004 Novell, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU Lesser General Public
7 * License as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 /* e2k-operation.c: Cancellable operations */
28 #include "e2k-operation.h"
30 static GStaticMutex op_mutex = G_STATIC_MUTEX_INIT;
31 static GHashTable *active_ops = NULL;
35 * @op: an #E2kOperation
37 * This initializes the #E2kOperation pointed to by @op.
38 * This should be called before passing @op to a cancellable function.
41 e2k_operation_init (E2kOperation *op)
43 g_return_if_fail (op != NULL);
45 memset (op, 0, sizeof (E2kOperation));
47 g_static_mutex_lock (&op_mutex);
49 active_ops = g_hash_table_new (NULL, NULL);
50 g_hash_table_insert (active_ops, op, op);
51 g_static_mutex_unlock (&op_mutex);
56 * @op: an #E2kOperation
58 * This frees @op and removes it from the list of active operations.
59 * It should be called after the function it was passed to returns.
62 e2k_operation_free (E2kOperation *op)
64 g_return_if_fail (op != NULL);
66 g_static_mutex_lock (&op_mutex);
67 g_hash_table_remove (active_ops, op);
68 g_static_mutex_unlock (&op_mutex);
73 * e2k_operation_start:
74 * @op: an #E2kOperation, or %NULL
75 * @canceller: the callback to invoke if @op is cancelled
76 * @owner: object that owns the operation
77 * @data: data to pass to @canceller
79 * This starts a single cancellable operation using @op. If @op has
80 * already been cancelled, this will invoke @canceller immediately.
82 * (If @op is %NULL, e2k_operation_start() is a no-op.)
85 e2k_operation_start (E2kOperation *op,
86 E2kOperationCancelFunc canceller,
93 g_static_mutex_lock (&op_mutex);
95 op->canceller = canceller;
99 if (op->cancelled && op->canceller) {
100 g_static_mutex_unlock (&op_mutex);
101 op->canceller (op, op->owner, op->data);
105 g_static_mutex_unlock (&op_mutex);
109 * e2k_operation_finish:
110 * @op: an #E2kOperation, or %NULL
112 * This finishes the current cancellable operation on @op. Attempting
113 * to cancel @op after this point will have no effect until another
114 * operation is started on it.
116 * (If @op is %NULL, e2k_operation_finish() is a no-op.)
119 e2k_operation_finish (E2kOperation *op)
124 g_static_mutex_lock (&op_mutex);
125 op->canceller = NULL;
128 g_static_mutex_unlock (&op_mutex);
133 * e2k_operation_cancel:
134 * @op: an #E2kOperation
136 * This cancels @op, invoking its cancellation callback. If @op is not
137 * an active operation, or has already been cancelled, this has no
141 e2k_operation_cancel (E2kOperation *op)
143 g_return_if_fail (op != NULL);
145 g_static_mutex_lock (&op_mutex);
147 if (!g_hash_table_lookup (active_ops, op) || op->cancelled) {
148 g_static_mutex_unlock (&op_mutex);
152 g_hash_table_remove (active_ops, op);
153 op->cancelled = TRUE;
154 g_static_mutex_unlock (&op_mutex);
157 op->canceller (op, op->owner, op->data);
161 * e2k_operation_is_cancelled:
162 * @op: an #E2kOperation (or %NULL)
164 * Checks if @op has been cancelled. Should only be called while @op
167 * Return value: whether or not @op has been cancelled.
170 e2k_operation_is_cancelled (E2kOperation *op)
172 return op && op->cancelled;