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 }