1 /* GIO - GLib Input, Output and Streaming Library 2 * 3 * Copyright (C) 2006-2007 Red Hat, Inc. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 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 GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General 16 * Public License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 18 * Boston, MA 02111-1307, USA. 19 * 20 * Author: Alexander Larsson <alexl (at) redhat.com> 21 */ 22 23 #include "config.h" 24 #ifdef HAVE_UNISTD_H 25 #include <unistd.h> 26 #endif 27 #include <fcntl.h> 28 #include <gioerror.h> 29 #ifdef G_OS_WIN32 30 #include <io.h> 31 #ifndef pipe 32 #define pipe(fds) _pipe(fds, 4096, _O_BINARY) 33 #endif 34 #endif 35 #include "gcancellable.h" 36 #include "glibintl.h" 37 38 #include "gioalias.h" 39 40 /** 41 * SECTION:gcancellable 42 * @short_description: Thread-safe Operation Cancellation Stack 43 * @include: gio/gio.h 44 * 45 * GCancellable is a thread-safe operation cancellation stack used 46 * throughout GIO to allow for cancellation of synchronous and 47 * asynchronous operations. 48 */ 49 50 enum { 51 CANCELLED, 52 LAST_SIGNAL 53 }; 54 55 struct _GCancellable 56 { 57 GObject parent_instance; 58 59 guint cancelled : 1; 60 guint allocated_pipe : 1; 61 int cancel_pipe[2]; 62 63 #ifdef G_OS_WIN32 64 GIOChannel *read_channel; 65 #endif 66 }; 67 68 static guint signals[LAST_SIGNAL] = { 0 }; 69 70 G_DEFINE_TYPE (GCancellable, g_cancellable, G_TYPE_OBJECT); 71 72 static GStaticPrivate current_cancellable = G_STATIC_PRIVATE_INIT; 73 G_LOCK_DEFINE_STATIC(cancellable); 74 75 static void 76 g_cancellable_finalize (GObject *object) 77 { 78 GCancellable *cancellable = G_CANCELLABLE (object); 79 80 if (cancellable->cancel_pipe[0] != -1) 81 close (cancellable->cancel_pipe[0]); 82 83 if (cancellable->cancel_pipe[1] != -1) 84 close (cancellable->cancel_pipe[1]); 85 86 #ifdef G_OS_WIN32 87 if (cancellable->read_channel) 88 g_io_channel_unref (cancellable->read_channel); 89 #endif 90 91 G_OBJECT_CLASS (g_cancellable_parent_class)->finalize (object); 92 } 93 94 static void 95 g_cancellable_class_init (GCancellableClass *klass) 96 { 97 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 98 99 gobject_class->finalize = g_cancellable_finalize; 100 101 /** 102 * GCancellable::cancelled: 103 * @cancellable: a #GCancellable. 104 * 105 * Emitted when the operation has been cancelled. 106 * 107 * Can be used by implementations of cancellable operations. If the 108 * operation is cancelled from another thread, the signal will be 109 * emitted in the thread that cancelled the operation, not the 110 * thread that is running the operation. 111 * 112 * Note that disconnecting from this signal (or any signal) in a 113 * multi-threaded program is prone to race conditions, and it is 114 * possible that a signal handler may be invoked even 115 * <emphasis>after</emphasis> a call to 116 * g_signal_handler_disconnect() for that handler has already 117 * returned. Therefore, code such as the following is wrong in a 118 * multi-threaded program: 119 * 120 * |[ 121 * my_data = my_data_new (...); 122 * id = g_signal_connect (cancellable, "cancelled", 123 * G_CALLBACK (cancelled_handler), my_data); 124 * 125 * /<!-- -->* cancellable operation here... *<!-- -->/ 126 * 127 * g_signal_handler_disconnect (cancellable, id); 128 * my_data_free (my_data); /<!-- -->* WRONG! *<!-- -->/ 129 * /<!-- -->* if g_cancellable_cancel() is called from another 130 * * thread, cancelled_handler() may be running at this point, 131 * * so it's not safe to free my_data. 132 * *<!-- -->/ 133 * ]| 134 * 135 * The correct way to free data (or otherwise clean up temporary 136 * state) in this situation is to use g_signal_connect_data() (or 137 * g_signal_connect_closure()) to connect to the signal, and do the 138 * cleanup from a #GClosureNotify, which will not be called until 139 * after the signal handler is both removed and not running: 140 * 141 * |[ 142 * static void 143 * cancelled_disconnect_notify (gpointer my_data, GClosure *closure) 144 * { 145 * my_data_free (my_data); 146 * } 147 * 148 * ... 149 * 150 * my_data = my_data_new (...); 151 * id = g_signal_connect_data (cancellable, "cancelled", 152 * G_CALLBACK (cancelled_handler), my_data, 153 * cancelled_disconnect_notify, 0); 154 * 155 * /<!-- -->* cancellable operation here... *<!-- -->/ 156 * 157 * g_signal_handler_disconnect (cancellable, id); 158 * /<!-- -->* cancelled_disconnect_notify() may or may not have 159 * * already been called at this point, so the code has to treat 160 * * my_data as though it has been freed. 161 * *<!-- -->/ 162 * ]| 163 */ 164 signals[CANCELLED] = 165 g_signal_new (I_("cancelled"), 166 G_TYPE_FROM_CLASS (gobject_class), 167 G_SIGNAL_RUN_LAST, 168 G_STRUCT_OFFSET (GCancellableClass, cancelled), 169 NULL, NULL, 170 g_cclosure_marshal_VOID__VOID, 171 G_TYPE_NONE, 0); 172 173 } 174 175 static void 176 set_fd_nonblocking (int fd) 177 { 178 #ifdef F_GETFL 179 glong fcntl_flags; 180 fcntl_flags = fcntl (fd, F_GETFL); 181 182 #ifdef O_NONBLOCK 183 fcntl_flags |= O_NONBLOCK; 184 #else 185 fcntl_flags |= O_NDELAY; 186 #endif 187 188 fcntl (fd, F_SETFL, fcntl_flags); 189 #endif 190 } 191 192 static void 193 g_cancellable_open_pipe (GCancellable *cancellable) 194 { 195 if (pipe (cancellable->cancel_pipe) == 0) 196 { 197 /* Make them nonblocking, just to be sure we don't block 198 * on errors and stuff 199 */ 200 set_fd_nonblocking (cancellable->cancel_pipe[0]); 201 set_fd_nonblocking (cancellable->cancel_pipe[1]); 202 } 203 else 204 g_warning ("Failed to create pipe for GCancellable. Out of file descriptors?"); 205 } 206 207 static void 208 g_cancellable_init (GCancellable *cancellable) 209 { 210 cancellable->cancel_pipe[0] = -1; 211 cancellable->cancel_pipe[1] = -1; 212 } 213 214 /** 215 * g_cancellable_new: 216 * 217 * Creates a new #GCancellable object. 218 * 219 * Applications that want to start one or more operations 220 * that should be cancellable should create a #GCancellable 221 * and pass it to the operations. 222 * 223 * One #GCancellable can be used in multiple consecutive 224 * operations, but not in multiple concurrent operations. 225 * 226 * Returns: a #GCancellable. 227 **/ 228 GCancellable * 229 g_cancellable_new (void) 230 { 231 return g_object_new (G_TYPE_CANCELLABLE, NULL); 232 } 233 234 /** 235 * g_cancellable_push_current: 236 * @cancellable: optional #GCancellable object, %NULL to ignore. 237 * 238 * Pushes @cancellable onto the cancellable stack. The current 239 * cancllable can then be recieved using g_cancellable_get_current(). 240 * 241 * This is useful when implementing cancellable operations in 242 * code that does not allow you to pass down the cancellable object. 243 * 244 * This is typically called automatically by e.g. #GFile operations, 245 * so you rarely have to call this yourself. 246 **/ 247 void 248 g_cancellable_push_current (GCancellable *cancellable) 249 { 250 GSList *l; 251 252 g_return_if_fail (cancellable != NULL); 253 254 l = g_static_private_get (¤t_cancellable); 255 l = g_slist_prepend (l, cancellable); 256 g_static_private_set (¤t_cancellable, l, NULL); 257 } 258 259 /** 260 * g_cancellable_pop_current: 261 * @cancellable: optional #GCancellable object, %NULL to ignore. 262 * 263 * Pops @cancellable off the cancellable stack (verifying that @cancellable 264 * is on the top of the stack). 265 **/ 266 void 267 g_cancellable_pop_current (GCancellable *cancellable) 268 { 269 GSList *l; 270 271 l = g_static_private_get (¤t_cancellable); 272 273 g_return_if_fail (l != NULL); 274 g_return_if_fail (l->data == cancellable); 275 276 l = g_slist_delete_link (l, l); 277 g_static_private_set (¤t_cancellable, l, NULL); 278 } 279 280 /** 281 * g_cancellable_get_current: 282 * 283 * Gets the top cancellable from the stack. 284 * 285 * Returns: a #GCancellable from the top of the stack, or %NULL 286 * if the stack is empty. 287 **/ 288 GCancellable * 289 g_cancellable_get_current (void) 290 { 291 GSList *l; 292 293 l = g_static_private_get (¤t_cancellable); 294 if (l == NULL) 295 return NULL; 296 297 return G_CANCELLABLE (l->data); 298 } 299 300 /** 301 * g_cancellable_reset: 302 * @cancellable: a #GCancellable object. 303 * 304 * Resets @cancellable to its uncancelled state. 305 **/ 306 void 307 g_cancellable_reset (GCancellable *cancellable) 308 { 309 g_return_if_fail (G_IS_CANCELLABLE (cancellable)); 310 311 G_LOCK(cancellable); 312 /* Make sure we're not leaving old cancel state around */ 313 if (cancellable->cancelled) 314 { 315 char ch; 316 #ifdef G_OS_WIN32 317 if (cancellable->read_channel) 318 { 319 gsize bytes_read; 320 g_io_channel_read_chars (cancellable->read_channel, &ch, 1, 321 &bytes_read, NULL); 322 } 323 else 324 #endif 325 if (cancellable->cancel_pipe[0] != -1) 326 read (cancellable->cancel_pipe[0], &ch, 1); 327 cancellable->cancelled = FALSE; 328 } 329 G_UNLOCK(cancellable); 330 } 331 332 /** 333 * g_cancellable_is_cancelled: 334 * @cancellable: a #GCancellable or NULL. 335 * 336 * Checks if a cancellable job has been cancelled. 337 * 338 * Returns: %TRUE if @cancellable is cancelled, 339 * FALSE if called with %NULL or if item is not cancelled. 340 **/ 341 gboolean 342 g_cancellable_is_cancelled (GCancellable *cancellable) 343 { 344 return cancellable != NULL && cancellable->cancelled; 345 } 346 347 /** 348 * g_cancellable_set_error_if_cancelled: 349 * @cancellable: a #GCancellable object. 350 * @error: #GError to append error state to. 351 * 352 * If the @cancellable is cancelled, sets the error to notify 353 * that the operation was cancelled. 354 * 355 * Returns: %TRUE if @cancellable was cancelled, %FALSE if it was not. 356 **/ 357 gboolean 358 g_cancellable_set_error_if_cancelled (GCancellable *cancellable, 359 GError **error) 360 { 361 if (g_cancellable_is_cancelled (cancellable)) 362 { 363 g_set_error_literal (error, 364 G_IO_ERROR, 365 G_IO_ERROR_CANCELLED, 366 _("Operation was cancelled")); 367 return TRUE; 368 } 369 370 return FALSE; 371 } 372 373 /** 374 * g_cancellable_get_fd: 375 * @cancellable: a #GCancellable. 376 * 377 * Gets the file descriptor for a cancellable job. This can be used to 378 * implement cancellable operations on Unix systems. The returned fd will 379 * turn readable when @cancellable is cancelled. 380 * 381 * See also g_cancellable_make_pollfd(). 382 * 383 * Returns: A valid file descriptor. %-1 if the file descriptor 384 * is not supported, or on errors. 385 **/ 386 int 387 g_cancellable_get_fd (GCancellable *cancellable) 388 { 389 int fd; 390 if (cancellable == NULL) 391 return -1; 392 393 G_LOCK(cancellable); 394 if (!cancellable->allocated_pipe) 395 { 396 cancellable->allocated_pipe = TRUE; 397 g_cancellable_open_pipe (cancellable); 398 } 399 400 fd = cancellable->cancel_pipe[0]; 401 G_UNLOCK(cancellable); 402 403 return fd; 404 } 405 406 /** 407 * g_cancellable_make_pollfd: 408 * @cancellable: a #GCancellable. 409 * @pollfd: a pointer to a #GPollFD 410 * 411 * Creates a #GPollFD corresponding to @cancellable; this can be passed 412 * to g_poll() and used to poll for cancellation. 413 **/ 414 void 415 g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd) 416 { 417 g_return_if_fail (G_IS_CANCELLABLE (cancellable)); 418 g_return_if_fail (pollfd != NULL); 419 420 #ifdef G_OS_WIN32 421 if (!cancellable->read_channel) 422 { 423 int fd = g_cancellable_get_fd (cancellable); 424 cancellable->read_channel = g_io_channel_win32_new_fd (fd); 425 g_io_channel_set_buffered (cancellable->read_channel, FALSE); 426 g_io_channel_set_flags (cancellable->read_channel, 427 G_IO_FLAG_NONBLOCK, NULL); 428 g_io_channel_set_encoding (cancellable->read_channel, NULL, NULL); 429 } 430 g_io_channel_win32_make_pollfd (cancellable->read_channel, G_IO_IN, pollfd); 431 /* (We need to keep cancellable->read_channel around, because it's 432 * keeping track of state related to the pollfd.) 433 */ 434 #else /* !G_OS_WIN32 */ 435 pollfd->fd = g_cancellable_get_fd (cancellable); 436 pollfd->events = G_IO_IN; 437 #endif /* G_OS_WIN32 */ 438 pollfd->revents = 0; 439 } 440 441 /** 442 * g_cancellable_cancel: 443 * @cancellable: a #GCancellable object. 444 * 445 * Will set @cancellable to cancelled, and will emit the 446 * #GCancellable::cancelled signal. (However, see the warning about 447 * race conditions in the documentation for that signal if you are 448 * planning to connect to it.) 449 * 450 * This function is thread-safe. In other words, you can safely call 451 * it from a thread other than the one running the operation that was 452 * passed the @cancellable. 453 * 454 * The convention within gio is that cancelling an asynchronous 455 * operation causes it to complete asynchronously. That is, if you 456 * cancel the operation from the same thread in which it is running, 457 * then the operation's #GAsyncReadyCallback will not be invoked until 458 * the application returns to the main loop. 459 **/ 460 void 461 g_cancellable_cancel (GCancellable *cancellable) 462 { 463 gboolean cancel; 464 465 cancel = FALSE; 466 467 G_LOCK(cancellable); 468 if (cancellable != NULL && 469 !cancellable->cancelled) 470 { 471 char ch = 'x'; 472 cancel = TRUE; 473 cancellable->cancelled = TRUE; 474 if (cancellable->cancel_pipe[1] != -1) 475 write (cancellable->cancel_pipe[1], &ch, 1); 476 } 477 G_UNLOCK(cancellable); 478 479 if (cancel) 480 { 481 g_object_ref (cancellable); 482 g_signal_emit (cancellable, signals[CANCELLED], 0); 483 g_object_unref (cancellable); 484 } 485 } 486 487 #define __G_CANCELLABLE_C__ 488 #include "gioaliasdef.c" 489