1. ------------------------------------------------------------------------------ 
  2. --                                                                          -- 
  3. --      Copyright (C) 1998-2000 E. Briot, J. Brobecker and A. Charlet       -- 
  4. --                     Copyright (C) 2000-2014, AdaCore                     -- 
  5. --                                                                          -- 
  6. -- This library is free software;  you can redistribute it and/or modify it -- 
  7. -- under terms of the  GNU General Public License  as published by the Free -- 
  8. -- Software  Foundation;  either version 3,  or (at your  option) any later -- 
  9. -- version. This library is distributed in the hope that it will be useful, -- 
  10. -- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- -- 
  11. -- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            -- 
  12. --                                                                          -- 
  13. -- As a special exception under Section 7 of GPL version 3, you are granted -- 
  14. -- additional permissions described in the GCC Runtime Library Exception,   -- 
  15. -- version 3.1, as published by the Free Software Foundation.               -- 
  16. --                                                                          -- 
  17. -- You should have received a copy of the GNU General Public License and    -- 
  18. -- a copy of the GCC Runtime Library Exception along with this program;     -- 
  19. -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    -- 
  20. -- <http://www.gnu.org/licenses/>.                                          -- 
  21. --                                                                          -- 
  22. ------------------------------------------------------------------------------ 
  23.  
  24. --  <description> 
  25. --  GCancellable is a thread-safe operation cancellation stack used throughout 
  26. --  GIO to allow for cancellation of synchronous and asynchronous operations. 
  27. -- 
  28. --  </description> 
  29. pragma Ada_2005; 
  30.  
  31. pragma Warnings (Off, "*is already use-visible*"); 
  32. with Glib;        use Glib; 
  33. with Glib.Main;   use Glib.Main; 
  34. with Glib.Object; use Glib.Object; 
  35.  
  36. package Glib.Cancellable is 
  37.  
  38.    type Gcancellable_Record is new GObject_Record with null record; 
  39.    type Gcancellable is access all Gcancellable_Record'Class; 
  40.  
  41.    --------------- 
  42.    -- Callbacks -- 
  43.    --------------- 
  44.  
  45.    type Gcallback is access procedure; 
  46.    --  The type used for callback functions in structure definitions and 
  47.    --  function signatures. This doesn't mean that all callback functions must 
  48.    --  take no parameters and return void. The required signature of a callback 
  49.    --  function is determined by the context in which is used (e.g. the signal 
  50.    --  to which it is connected). Use G_CALLBACK to cast the callback function 
  51.    --  to a Gcallback. 
  52.  
  53.    ------------------ 
  54.    -- Constructors -- 
  55.    ------------------ 
  56.  
  57.    procedure G_New (Self : out Gcancellable); 
  58.    --  Creates a new Glib.Cancellable.Gcancellable object. 
  59.    --  Applications that want to start one or more operations that should be 
  60.    --  cancellable should create a Glib.Cancellable.Gcancellable and pass it to 
  61.    --  the operations. 
  62.    --  One Glib.Cancellable.Gcancellable can be used in multiple consecutive 
  63.    --  operations or in multiple concurrent operations. 
  64.  
  65.    procedure Initialize (Self : not null access Gcancellable_Record'Class); 
  66.    --  Creates a new Glib.Cancellable.Gcancellable object. 
  67.    --  Applications that want to start one or more operations that should be 
  68.    --  cancellable should create a Glib.Cancellable.Gcancellable and pass it to 
  69.    --  the operations. 
  70.    --  One Glib.Cancellable.Gcancellable can be used in multiple consecutive 
  71.    --  operations or in multiple concurrent operations. 
  72.  
  73.    function Gcancellable_New return Gcancellable; 
  74.    --  Creates a new Glib.Cancellable.Gcancellable object. 
  75.    --  Applications that want to start one or more operations that should be 
  76.    --  cancellable should create a Glib.Cancellable.Gcancellable and pass it to 
  77.    --  the operations. 
  78.    --  One Glib.Cancellable.Gcancellable can be used in multiple consecutive 
  79.    --  operations or in multiple concurrent operations. 
  80.  
  81.    function Get_Type return Glib.GType; 
  82.    pragma Import (C, Get_Type, "g_cancellable_get_type"); 
  83.  
  84.    ------------- 
  85.    -- Methods -- 
  86.    ------------- 
  87.  
  88.    procedure Cancel (Self : not null access Gcancellable_Record); 
  89.    --  Will set Cancellable to cancelled, and will emit the 
  90.    --  Glib.Cancellable.Gcancellable::cancelled signal. (However, see the 
  91.    --  warning about race conditions in the documentation for that signal if 
  92.    --  you are planning to connect to it.) 
  93.    --  This function is thread-safe. In other words, you can safely call it 
  94.    --  from a thread other than the one running the operation that was passed 
  95.    --  the Cancellable. 
  96.    --  The convention within gio is that cancelling an asynchronous operation 
  97.    --  causes it to complete asynchronously. That is, if you cancel the 
  98.    --  operation from the same thread in which it is running, then the 
  99.    --  operation's Gasync_Ready_Callback will not be invoked until the 
  100.    --  application returns to the main loop. 
  101.  
  102.    function Connect 
  103.       (Self              : not null access Gcancellable_Record; 
  104.        Callback          : Gcallback; 
  105.        Data_Destroy_Func : Glib.G_Destroy_Notify_Address) return Gulong; 
  106.    --  Convenience function to connect to the 
  107.    --  Glib.Cancellable.Gcancellable::cancelled signal. Also handles the race 
  108.    --  condition that may happen if the cancellable is cancelled right before 
  109.    --  connecting. 
  110.    --  Callback is called at most once, either directly at the time of the 
  111.    --  connect if Cancellable is already cancelled, or when Cancellable is 
  112.    --  cancelled in some thread. 
  113.    --  Data_Destroy_Func will be called when the handler is disconnected, or 
  114.    --  immediately if the cancellable is already cancelled. 
  115.    --  See Glib.Cancellable.Gcancellable::cancelled for details on how to use 
  116.    --  this. 
  117.    --  Since: gtk+ 2.22 
  118.    --  "callback": The Gcallback to connect. 
  119.    --  "data_destroy_func": Free function for Data or null. 
  120.  
  121.    generic 
  122.       type User_Data_Type (<>) is private; 
  123.       with procedure Destroy (Data : in out User_Data_Type) is null; 
  124.    package Connect_User_Data is 
  125.  
  126.       type Gcallback is access procedure (Data : User_Data_Type); 
  127.       --  The type used for callback functions in structure definitions and 
  128.       --  function signatures. This doesn't mean that all callback functions must 
  129.       --  take no parameters and return void. The required signature of a callback 
  130.       --  function is determined by the context in which is used (e.g. the signal 
  131.       --  to which it is connected). Use G_CALLBACK to cast the callback function 
  132.       --  to a Gcallback. 
  133.  
  134.       function Connect 
  135.          (Self              : not null access Glib.Cancellable.Gcancellable_Record'Class; 
  136.           Callback          : Gcallback; 
  137.           Data              : User_Data_Type; 
  138.           Data_Destroy_Func : Glib.G_Destroy_Notify_Address) return Gulong; 
  139.       --  Convenience function to connect to the 
  140.       --  Glib.Cancellable.Gcancellable::cancelled signal. Also handles the 
  141.       --  race condition that may happen if the cancellable is cancelled right 
  142.       --  before connecting. 
  143.       --  Callback is called at most once, either directly at the time of the 
  144.       --  connect if Cancellable is already cancelled, or when Cancellable is 
  145.       --  cancelled in some thread. 
  146.       --  Data_Destroy_Func will be called when the handler is disconnected, 
  147.       --  or immediately if the cancellable is already cancelled. 
  148.       --  See Glib.Cancellable.Gcancellable::cancelled for details on how to 
  149.       --  use this. 
  150.       --  Since: gtk+ 2.22 
  151.       --  "callback": The Gcallback to connect. 
  152.       --  "data": Data to pass to Callback. 
  153.       --  "data_destroy_func": Free function for Data or null. 
  154.  
  155.    end Connect_User_Data; 
  156.  
  157.    procedure Disconnect 
  158.       (Self       : not null access Gcancellable_Record; 
  159.        Handler_Id : Gulong); 
  160.    --  Disconnects a handler from a cancellable instance similar to 
  161.    --  g_signal_handler_disconnect. Additionally, in the event that a signal 
  162.    --  handler is currently running, this call will block until the handler has 
  163.    --  finished. Calling this function from a 
  164.    --  Glib.Cancellable.Gcancellable::cancelled signal handler will therefore 
  165.    --  result in a deadlock. 
  166.    --  This avoids a race condition where a thread cancels at the same time as 
  167.    --  the cancellable operation is finished and the signal handler is removed. 
  168.    --  See Glib.Cancellable.Gcancellable::cancelled for details on how to use 
  169.    --  this. 
  170.    --  If Cancellable is null or Handler_Id is %0 this function does nothing. 
  171.    --  Since: gtk+ 2.22 
  172.    --  "handler_id": Handler id of the handler to be disconnected, or %0. 
  173.  
  174.    function Get_Fd (Self : not null access Gcancellable_Record) return Gint; 
  175.    --  Gets the file descriptor for a cancellable job. This can be used to 
  176.    --  implement cancellable operations on Unix systems. The returned fd will 
  177.    --  turn readable when Cancellable is cancelled. 
  178.    --  You are not supposed to read from the fd yourself, just check for 
  179.    --  readable status. Reading to unset the readable status is done with 
  180.    --  Glib.Cancellable.Reset. 
  181.    --  After a successful return from this function, you should use 
  182.    --  Glib.Cancellable.Release_Fd to free up resources allocated for the 
  183.    --  returned file descriptor. 
  184.    --  See also g_cancellable_make_pollfd. 
  185.  
  186.    function Is_Cancelled 
  187.       (Self : not null access Gcancellable_Record) return Boolean; 
  188.    --  Checks if a cancellable job has been cancelled. 
  189.  
  190.    procedure Pop_Current (Self : not null access Gcancellable_Record); 
  191.    --  Pops Cancellable off the cancellable stack (verifying that Cancellable 
  192.    --  is on the top of the stack). 
  193.  
  194.    procedure Push_Current (Self : not null access Gcancellable_Record); 
  195.    --  Pushes Cancellable onto the cancellable stack. The current cancellable 
  196.    --  can then be received using Glib.Cancellable.Get_Current. 
  197.    --  This is useful when implementing cancellable operations in code that 
  198.    --  does not allow you to pass down the cancellable object. 
  199.    --  This is typically called automatically by e.g. Gfile.Gfile operations, 
  200.    --  so you rarely have to call this yourself. 
  201.  
  202.    procedure Release_Fd (Self : not null access Gcancellable_Record); 
  203.    --  Releases a resources previously allocated by Glib.Cancellable.Get_Fd or 
  204.    --  g_cancellable_make_pollfd. 
  205.    --  For compatibility reasons with older releases, calling this function is 
  206.    --  not strictly required, the resources will be automatically freed when 
  207.    --  the Cancellable is finalized. However, the Cancellable will block scarce 
  208.    --  file descriptors until it is finalized if this function is not called. 
  209.    --  This can cause the application to run out of file descriptors when many 
  210.    --  GCancellables are used at the same time. 
  211.    --  Since: gtk+ 2.22 
  212.  
  213.    procedure Reset (Self : not null access Gcancellable_Record); 
  214.    --  Resets Cancellable to its uncancelled state. 
  215.    --  If cancellable is currently in use by any cancellable operation then 
  216.    --  the behavior of this function is undefined. 
  217.  
  218.    function Set_Error_If_Cancelled 
  219.       (Self : not null access Gcancellable_Record) return Boolean; 
  220.    --  If the Cancellable is cancelled, sets the error to notify that the 
  221.    --  operation was cancelled. 
  222.  
  223.    function Source_New 
  224.       (Self : not null access Gcancellable_Record) return Glib.Main.G_Source; 
  225.    --  Creates a source that triggers if Cancellable is cancelled and calls 
  226.    --  its callback of type Gcancellable_Source_Func. This is primarily useful 
  227.    --  for attaching to another (non-cancellable) source with 
  228.    --  g_source_add_child_source to add cancellability to it. 
  229.    --  For convenience, you can call this with a null 
  230.    --  Glib.Cancellable.Gcancellable, in which case the source will never 
  231.    --  trigger. 
  232.    --  Since: gtk+ 2.28 
  233.  
  234.    --------------- 
  235.    -- Functions -- 
  236.    --------------- 
  237.  
  238.    function Get_Current return Gcancellable; 
  239.    --  Gets the top cancellable from the stack. 
  240.  
  241.    ------------- 
  242.    -- Signals -- 
  243.    ------------- 
  244.  
  245.    type Cb_Gcancellable_Void is not null access procedure (Self : access Gcancellable_Record'Class); 
  246.  
  247.    type Cb_GObject_Void is not null access procedure 
  248.      (Self : access Glib.Object.GObject_Record'Class); 
  249.  
  250.    Signal_Cancelled : constant Glib.Signal_Name := "cancelled"; 
  251.    procedure On_Cancelled 
  252.       (Self  : not null access Gcancellable_Record; 
  253.        Call  : Cb_Gcancellable_Void; 
  254.        After : Boolean := False); 
  255.    procedure On_Cancelled 
  256.       (Self  : not null access Gcancellable_Record; 
  257.        Call  : Cb_GObject_Void; 
  258.        Slot  : not null access Glib.Object.GObject_Record'Class; 
  259.        After : Boolean := False); 
  260.    --  Emitted when the operation has been cancelled. 
  261.    -- 
  262.    --  Can be used by implementations of cancellable operations. If the 
  263.    --  operation is cancelled from another thread, the signal will be emitted 
  264.    --  in the thread that cancelled the operation, not the thread that is 
  265.    --  running the operation. 
  266.    -- 
  267.    --  Note that disconnecting from this signal (or any signal) in a 
  268.    --  multi-threaded program is prone to race conditions. For instance it is 
  269.    --  possible that a signal handler may be invoked even *after* a call to 
  270.    --  g_signal_handler_disconnect for that handler has already returned. 
  271.    -- 
  272.    --  There is also a problem when cancellation happen right before 
  273.    --  connecting to the signal. If this happens the signal will unexpectedly 
  274.    --  not be emitted, and checking before connecting to the signal leaves a 
  275.    --  race condition where this is still happening. 
  276.    -- 
  277.    --  In order to make it safe and easy to connect handlers there are two 
  278.    --  helper functions: Glib.Cancellable.Connect and 
  279.    --  Glib.Cancellable.Disconnect which protect against problems like this. 
  280.    -- 
  281.    --  An example of how to us this: |[ /<!-- -->* Make sure we don't do any 
  282.    --  unnecessary work if already cancelled *<!-- -->/ if 
  283.    --  (g_cancellable_set_error_if_cancelled (cancellable)) return; 
  284.    -- 
  285.    --  /<!-- -->* Set up all the data needed to be able to * handle 
  286.    --  cancellation of the operation *<!-- -->/ my_data = my_data_new (...); 
  287.    -- 
  288.    --  id = 0; if (cancellable) id = g_cancellable_connect (cancellable, 
  289.    --  G_CALLBACK (cancelled_handler) data, NULL); 
  290.    -- 
  291.    --  /<!-- -->* cancellable operation here... *<!-- -->/ 
  292.    -- 
  293.    --  g_cancellable_disconnect (cancellable, id); 
  294.    -- 
  295.    --  /<!-- -->* cancelled_handler is never called after this, it * is now 
  296.    --  safe to free the data *<!-- -->/ my_data_free (my_data); ]| 
  297.    -- 
  298.    --  Note that the cancelled signal is emitted in the thread that the user 
  299.    --  cancelled from, which may be the main thread. So, the cancellable signal 
  300.    --  should not do something that can block. 
  301.  
  302. end Glib.Cancellable;