ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm
[gnome-vfs-httpcaptive.git] / libgnomevfs / gnome-vfs-cancellation.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gnome-vfs-cancellation.c - Cancellation handling for the GNOME Virtual File
3    System access methods.
4
5    Copyright (C) 1999 Free Software Foundation
6
7    The Gnome Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11
12    The Gnome Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public
18    License along with the Gnome Library; see the file COPYING.LIB.  If not,
19    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21
22    Author: Ettore Perazzoli <ettore@gnu.org> */
23
24 #include <config.h>
25 #include "gnome-vfs-cancellation.h"
26
27 #include "gnome-vfs-utils.h"
28 #include <unistd.h>
29
30 /* WARNING: this code is not general-purpose.  It is supposed to make the two
31    sides of the VFS (i.e. the main process/thread and its asynchronous slave)
32    talk in a simple way.  For this reason, only the main process/thread should
33    be allowed to call `gnome_vfs_cancellation_cancel()'.  *All* the code is
34    based on this assumption.  */
35
36 \f
37 struct GnomeVFSCancellation {
38         gboolean cancelled;
39         gint pipe_in;
40         gint pipe_out;
41 };
42
43 \f
44 /**
45  * gnome_vfs_cancellation_new:
46  * 
47  * Create a new GnomeVFSCancellation object for reporting cancellation to a
48  * GNOME VFS module.
49  * 
50  * Return value: A pointer to the new GnomeVFSCancellation object.
51  **/
52 GnomeVFSCancellation *
53 gnome_vfs_cancellation_new (void)
54 {
55         GnomeVFSCancellation *new;
56
57         new = g_new (GnomeVFSCancellation, 1);
58         new->cancelled = FALSE;
59         new->pipe_in = -1;
60         new->pipe_out = -1;
61
62         return new;
63 }
64
65 /**
66  * gnome_vfs_cancellation_destroy:
67  * @cancellation: A GnomeVFSCancellation object
68  * 
69  * Destroy @cancellation.
70  **/
71 void
72 gnome_vfs_cancellation_destroy (GnomeVFSCancellation *cancellation)
73 {
74         g_return_if_fail (cancellation != NULL);
75
76         if (cancellation->pipe_in >= 0) {
77                 close (cancellation->pipe_in);
78                 close (cancellation->pipe_out);
79         }
80         g_free (cancellation);
81 }
82
83 /**
84  * gnome_vfs_cancellation_cancel:
85  * @cancellation: A GnomeVFSCancellation object
86  * 
87  * Send a cancellation request through @cancellation.
88  **/
89 void
90 gnome_vfs_cancellation_cancel (GnomeVFSCancellation *cancellation)
91 {
92         g_return_if_fail (cancellation != NULL);
93
94         GNOME_VFS_ASSERT_PRIMARY_THREAD;
95
96         if (cancellation->cancelled)
97                 return;
98
99         if (cancellation->pipe_out >= 0)
100                 write (cancellation->pipe_out, "c", 1);
101
102         cancellation->cancelled = TRUE;
103 }
104
105 /**
106  * gnome_vfs_cancellation_check:
107  * @cancellation: A GnomeVFSCancellation object
108  * 
109  * Check for pending cancellation.
110  * 
111  * Return value: %TRUE if the operation should be interrupted.
112  **/
113 gboolean
114 gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation)
115 {
116         if (cancellation == NULL)
117                 return FALSE;
118
119         return cancellation->cancelled;
120 }
121
122 /**
123  * gnome_vfs_cancellation_ack:
124  * @cancellation: A GnomeVFSCancellation object
125  * 
126  * Acknowledge a cancellation.  This should be called if
127  * `gnome_vfs_cancellation_check()' returns %TRUE or if `select()' reports that
128  * input is available on the file descriptor returned by
129  * `gnome_vfs_cancellation_get_fd()'.
130  **/
131 void
132 gnome_vfs_cancellation_ack (GnomeVFSCancellation *cancellation)
133 {
134         gchar c;
135
136         if (cancellation == NULL)
137                 return;
138
139         if (cancellation->pipe_in >= 0)
140                 read (cancellation->pipe_in, &c, 1);
141
142         cancellation->cancelled = FALSE;
143 }
144
145 /**
146  * gnome_vfs_cancellation_get_fd:
147  * @cancellation: A GnomeVFSCancellation object
148  * 
149  * Get a file descriptor -based notificator for @cancellation.  When
150  * @cancellation receives a cancellation request, a character will be made
151  * available on the returned file descriptor for input.
152  *
153  * This is very useful for detecting cancellation during I/O operations: you
154  * can use the `select()' call to check for available input/output on the file
155  * you are reading/writing, and on the notificator's file descriptor at the
156  * same time.  If a data is available on the notificator's file descriptor, you
157  * know you have to cancel the read/write operation.
158  * 
159  * Return value: the notificator's file descriptor, or -1 if starved of
160  *               file descriptors.
161  **/
162 gint
163 gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation)
164 {
165         g_return_val_if_fail (cancellation != NULL, -1);
166
167         if (cancellation->pipe_in <= 0) {
168                 gint pipefd [2];
169
170                 if (pipe (pipefd) == -1)
171                         return -1;
172
173                 cancellation->pipe_in = pipefd [0];
174                 cancellation->pipe_out = pipefd [1];
175         }
176
177         return cancellation->pipe_in;
178 }