1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD 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 for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.Cancellable; 26 27 private import glib.ConstructionException; 28 private import glib.ErrorG; 29 private import glib.GException; 30 private import glib.Source; 31 private import gobject.ObjectG; 32 private import gobject.Signals; 33 public import gtkc.gdktypes; 34 private import gtkc.gio; 35 public import gtkc.giotypes; 36 private import std.algorithm; 37 38 39 /** 40 * GCancellable is a thread-safe operation cancellation stack used 41 * throughout GIO to allow for cancellation of synchronous and 42 * asynchronous operations. 43 */ 44 public class Cancellable : ObjectG 45 { 46 /** the main Gtk struct */ 47 protected GCancellable* gCancellable; 48 49 /** Get the main Gtk struct */ 50 public GCancellable* getCancellableStruct() 51 { 52 return gCancellable; 53 } 54 55 /** the main Gtk struct as a void* */ 56 protected override void* getStruct() 57 { 58 return cast(void*)gCancellable; 59 } 60 61 protected override void setStruct(GObject* obj) 62 { 63 gCancellable = cast(GCancellable*)obj; 64 super.setStruct(obj); 65 } 66 67 /** 68 * Sets our main struct and passes it to the parent class. 69 */ 70 public this (GCancellable* gCancellable, bool ownedRef = false) 71 { 72 this.gCancellable = gCancellable; 73 super(cast(GObject*)gCancellable, ownedRef); 74 } 75 76 77 /** */ 78 public static GType getType() 79 { 80 return g_cancellable_get_type(); 81 } 82 83 /** 84 * Creates a new #GCancellable object. 85 * 86 * Applications that want to start one or more operations 87 * that should be cancellable should create a #GCancellable 88 * and pass it to the operations. 89 * 90 * One #GCancellable can be used in multiple consecutive 91 * operations or in multiple concurrent operations. 92 * 93 * Return: a #GCancellable. 94 * 95 * Throws: ConstructionException GTK+ fails to create the object. 96 */ 97 public this() 98 { 99 auto p = g_cancellable_new(); 100 101 if(p is null) 102 { 103 throw new ConstructionException("null returned by new"); 104 } 105 106 this(cast(GCancellable*) p, true); 107 } 108 109 /** 110 * Gets the top cancellable from the stack. 111 * 112 * Return: a #GCancellable from the top 113 * of the stack, or %NULL if the stack is empty. 114 */ 115 public static Cancellable getCurrent() 116 { 117 auto p = g_cancellable_get_current(); 118 119 if(p is null) 120 { 121 return null; 122 } 123 124 return ObjectG.getDObject!(Cancellable)(cast(GCancellable*) p); 125 } 126 127 /** 128 * Will set @cancellable to cancelled, and will emit the 129 * #GCancellable::cancelled signal. (However, see the warning about 130 * race conditions in the documentation for that signal if you are 131 * planning to connect to it.) 132 * 133 * This function is thread-safe. In other words, you can safely call 134 * it from a thread other than the one running the operation that was 135 * passed the @cancellable. 136 * 137 * If @cancellable is %NULL, this function returns immediately for convenience. 138 * 139 * The convention within GIO is that cancelling an asynchronous 140 * operation causes it to complete asynchronously. That is, if you 141 * cancel the operation from the same thread in which it is running, 142 * then the operation's #GAsyncReadyCallback will not be invoked until 143 * the application returns to the main loop. 144 */ 145 public void cancel() 146 { 147 g_cancellable_cancel(gCancellable); 148 } 149 150 /** 151 * Convenience function to connect to the #GCancellable::cancelled 152 * signal. Also handles the race condition that may happen 153 * if the cancellable is cancelled right before connecting. 154 * 155 * @callback is called at most once, either directly at the 156 * time of the connect if @cancellable is already cancelled, 157 * or when @cancellable is cancelled in some thread. 158 * 159 * @data_destroy_func will be called when the handler is 160 * disconnected, or immediately if the cancellable is already 161 * cancelled. 162 * 163 * See #GCancellable::cancelled for details on how to use this. 164 * 165 * Since GLib 2.40, the lock protecting @cancellable is not held when 166 * @callback is invoked. This lifts a restriction in place for 167 * earlier GLib versions which now makes it easier to write cleanup 168 * code that unconditionally invokes e.g. g_cancellable_cancel(). 169 * 170 * Params: 171 * callback = The #GCallback to connect. 172 * data = Data to pass to @callback. 173 * dataDestroyFunc = Free function for @data or %NULL. 174 * 175 * Return: The id of the signal handler or 0 if @cancellable has already 176 * been cancelled. 177 * 178 * Since: 2.22 179 */ 180 public gulong connect(GCallback callback, void* data, GDestroyNotify dataDestroyFunc) 181 { 182 return g_cancellable_connect(gCancellable, callback, data, dataDestroyFunc); 183 } 184 185 /** 186 * Disconnects a handler from a cancellable instance similar to 187 * g_signal_handler_disconnect(). Additionally, in the event that a 188 * signal handler is currently running, this call will block until the 189 * handler has finished. Calling this function from a 190 * #GCancellable::cancelled signal handler will therefore result in a 191 * deadlock. 192 * 193 * This avoids a race condition where a thread cancels at the 194 * same time as the cancellable operation is finished and the 195 * signal handler is removed. See #GCancellable::cancelled for 196 * details on how to use this. 197 * 198 * If @cancellable is %NULL or @handler_id is %0 this function does 199 * nothing. 200 * 201 * Params: 202 * handlerId = Handler id of the handler to be disconnected, or %0. 203 * 204 * Since: 2.22 205 */ 206 public void disconnect(gulong handlerId) 207 { 208 g_cancellable_disconnect(gCancellable, handlerId); 209 } 210 211 /** 212 * Gets the file descriptor for a cancellable job. This can be used to 213 * implement cancellable operations on Unix systems. The returned fd will 214 * turn readable when @cancellable is cancelled. 215 * 216 * You are not supposed to read from the fd yourself, just check for 217 * readable status. Reading to unset the readable status is done 218 * with g_cancellable_reset(). 219 * 220 * After a successful return from this function, you should use 221 * g_cancellable_release_fd() to free up resources allocated for 222 * the returned file descriptor. 223 * 224 * See also g_cancellable_make_pollfd(). 225 * 226 * Return: A valid file descriptor. %-1 if the file descriptor 227 * is not supported, or on errors. 228 */ 229 public int getFd() 230 { 231 return g_cancellable_get_fd(gCancellable); 232 } 233 234 /** 235 * Checks if a cancellable job has been cancelled. 236 * 237 * Return: %TRUE if @cancellable is cancelled, 238 * FALSE if called with %NULL or if item is not cancelled. 239 */ 240 public bool isCancelled() 241 { 242 return g_cancellable_is_cancelled(gCancellable) != 0; 243 } 244 245 /** 246 * Creates a #GPollFD corresponding to @cancellable; this can be passed 247 * to g_poll() and used to poll for cancellation. This is useful both 248 * for unix systems without a native poll and for portability to 249 * windows. 250 * 251 * When this function returns %TRUE, you should use 252 * g_cancellable_release_fd() to free up resources allocated for the 253 * @pollfd. After a %FALSE return, do not call g_cancellable_release_fd(). 254 * 255 * If this function returns %FALSE, either no @cancellable was given or 256 * resource limits prevent this function from allocating the necessary 257 * structures for polling. (On Linux, you will likely have reached 258 * the maximum number of file descriptors.) The suggested way to handle 259 * these cases is to ignore the @cancellable. 260 * 261 * You are not supposed to read from the fd yourself, just check for 262 * readable status. Reading to unset the readable status is done 263 * with g_cancellable_reset(). 264 * 265 * Params: 266 * pollfd = a pointer to a #GPollFD 267 * 268 * Return: %TRUE if @pollfd was successfully initialized, %FALSE on 269 * failure to prepare the cancellable. 270 * 271 * Since: 2.22 272 */ 273 public bool makePollfd(GPollFD* pollfd) 274 { 275 return g_cancellable_make_pollfd(gCancellable, pollfd) != 0; 276 } 277 278 /** 279 * Pops @cancellable off the cancellable stack (verifying that @cancellable 280 * is on the top of the stack). 281 */ 282 public void popCurrent() 283 { 284 g_cancellable_pop_current(gCancellable); 285 } 286 287 /** 288 * Pushes @cancellable onto the cancellable stack. The current 289 * cancellable can then be received using g_cancellable_get_current(). 290 * 291 * This is useful when implementing cancellable operations in 292 * code that does not allow you to pass down the cancellable object. 293 * 294 * This is typically called automatically by e.g. #GFile operations, 295 * so you rarely have to call this yourself. 296 */ 297 public void pushCurrent() 298 { 299 g_cancellable_push_current(gCancellable); 300 } 301 302 /** 303 * Releases a resources previously allocated by g_cancellable_get_fd() 304 * or g_cancellable_make_pollfd(). 305 * 306 * For compatibility reasons with older releases, calling this function 307 * is not strictly required, the resources will be automatically freed 308 * when the @cancellable is finalized. However, the @cancellable will 309 * block scarce file descriptors until it is finalized if this function 310 * is not called. This can cause the application to run out of file 311 * descriptors when many #GCancellables are used at the same time. 312 * 313 * Since: 2.22 314 */ 315 public void releaseFd() 316 { 317 g_cancellable_release_fd(gCancellable); 318 } 319 320 /** 321 * Resets @cancellable to its uncancelled state. 322 * 323 * If cancellable is currently in use by any cancellable operation 324 * then the behavior of this function is undefined. 325 * 326 * Note that it is generally not a good idea to reuse an existing 327 * cancellable for more operations after it has been cancelled once, 328 * as this function might tempt you to do. The recommended practice 329 * is to drop the reference to a cancellable after cancelling it, 330 * and let it die with the outstanding async operations. You should 331 * create a fresh cancellable for further async operations. 332 */ 333 public void reset() 334 { 335 g_cancellable_reset(gCancellable); 336 } 337 338 /** 339 * If the @cancellable is cancelled, sets the error to notify 340 * that the operation was cancelled. 341 * 342 * Return: %TRUE if @cancellable was cancelled, %FALSE if it was not 343 * 344 * Throws: GException on failure. 345 */ 346 public bool setErrorIfCancelled() 347 { 348 GError* err = null; 349 350 auto p = g_cancellable_set_error_if_cancelled(gCancellable, &err) != 0; 351 352 if (err !is null) 353 { 354 throw new GException( new ErrorG(err) ); 355 } 356 357 return p; 358 } 359 360 /** 361 * Creates a source that triggers if @cancellable is cancelled and 362 * calls its callback of type #GCancellableSourceFunc. This is 363 * primarily useful for attaching to another (non-cancellable) source 364 * with g_source_add_child_source() to add cancellability to it. 365 * 366 * For convenience, you can call this with a %NULL #GCancellable, 367 * in which case the source will never trigger. 368 * 369 * The new #GSource will hold a reference to the #GCancellable. 370 * 371 * Return: the new #GSource. 372 * 373 * Since: 2.28 374 */ 375 public Source sourceNew() 376 { 377 auto p = g_cancellable_source_new(gCancellable); 378 379 if(p is null) 380 { 381 return null; 382 } 383 384 return new Source(cast(GSource*) p, true); 385 } 386 387 protected class OnCancelledDelegateWrapper 388 { 389 void delegate(Cancellable) dlg; 390 gulong handlerId; 391 ConnectFlags flags; 392 this(void delegate(Cancellable) dlg, gulong handlerId, ConnectFlags flags) 393 { 394 this.dlg = dlg; 395 this.handlerId = handlerId; 396 this.flags = flags; 397 } 398 } 399 protected OnCancelledDelegateWrapper[] onCancelledListeners; 400 401 /** 402 * Emitted when the operation has been cancelled. 403 * 404 * Can be used by implementations of cancellable operations. If the 405 * operation is cancelled from another thread, the signal will be 406 * emitted in the thread that cancelled the operation, not the 407 * thread that is running the operation. 408 * 409 * Note that disconnecting from this signal (or any signal) in a 410 * multi-threaded program is prone to race conditions. For instance 411 * it is possible that a signal handler may be invoked even after 412 * a call to g_signal_handler_disconnect() for that handler has 413 * already returned. 414 * 415 * There is also a problem when cancellation happens right before 416 * connecting to the signal. If this happens the signal will 417 * unexpectedly not be emitted, and checking before connecting to 418 * the signal leaves a race condition where this is still happening. 419 * 420 * In order to make it safe and easy to connect handlers there 421 * are two helper functions: g_cancellable_connect() and 422 * g_cancellable_disconnect() which protect against problems 423 * like this. 424 * 425 * An example of how to us this: 426 * |[<!-- language="C" --> 427 * // Make sure we don't do unnecessary work if already cancelled 428 * if (g_cancellable_set_error_if_cancelled (cancellable, error)) 429 * return; 430 * 431 * // Set up all the data needed to be able to handle cancellation 432 * // of the operation 433 * my_data = my_data_new (...); 434 * 435 * id = 0; 436 * if (cancellable) 437 * id = g_cancellable_connect (cancellable, 438 * G_CALLBACK (cancelled_handler) 439 * data, NULL); 440 * 441 * // cancellable operation here... 442 * 443 * g_cancellable_disconnect (cancellable, id); 444 * 445 * // cancelled_handler is never called after this, it is now safe 446 * // to free the data 447 * my_data_free (my_data); 448 * ]| 449 * 450 * Note that the cancelled signal is emitted in the thread that 451 * the user cancelled from, which may be the main thread. So, the 452 * cancellable signal should not do something that can block. 453 */ 454 gulong addOnCancelled(void delegate(Cancellable) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 455 { 456 onCancelledListeners ~= new OnCancelledDelegateWrapper(dlg, 0, connectFlags); 457 onCancelledListeners[onCancelledListeners.length - 1].handlerId = Signals.connectData( 458 this, 459 "cancelled", 460 cast(GCallback)&callBackCancelled, 461 cast(void*)onCancelledListeners[onCancelledListeners.length - 1], 462 cast(GClosureNotify)&callBackCancelledDestroy, 463 connectFlags); 464 return onCancelledListeners[onCancelledListeners.length - 1].handlerId; 465 } 466 467 extern(C) static void callBackCancelled(GCancellable* cancellableStruct,OnCancelledDelegateWrapper wrapper) 468 { 469 wrapper.dlg(wrapper.outer); 470 } 471 472 extern(C) static void callBackCancelledDestroy(OnCancelledDelegateWrapper wrapper, GClosure* closure) 473 { 474 wrapper.outer.internalRemoveOnCancelled(wrapper); 475 } 476 477 protected void internalRemoveOnCancelled(OnCancelledDelegateWrapper source) 478 { 479 foreach(index, wrapper; onCancelledListeners) 480 { 481 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 482 { 483 onCancelledListeners[index] = null; 484 onCancelledListeners = std.algorithm.remove(onCancelledListeners, index); 485 break; 486 } 487 } 488 } 489 490 }