Imported Upstream version 3.1.0
[debian/amanda] / xfer-src / xfer.h
1 /*
2  * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  */
20
21 /* An Xfer abstracts an active data transfer through the Amanda core.
22  */
23
24 #ifndef XFER_H
25 #define XFER_H
26
27 #include <glib.h>
28
29 /* An Xfer represents a flow of data from a source, via zero or more filters,
30  * to a destination.  Sources, filters, and destinations are "transfer elements".
31  * The job of the Xfer is glue together a sequence of elements, and provide a
32  * dispatch point for messages from those elements to the caller.
33  *
34  * Xfers are not implemented as GObjects because there is no reason to subclass an
35  * Xfer or apply any of the other features that come with GObject.
36  */
37
38 /* The moment-to-moment state of a transfer */
39 typedef enum {
40     XFER_INIT = 1,      /* initializing */
41     XFER_START = 2,     /* starting */
42     XFER_RUNNING = 3,   /* data flowing */
43     XFER_CANCELLING = 4,/* cancellation begun */
44     XFER_CANCELLED = 5, /* all elements cancelled; draining data */
45     XFER_DONE = 6,      /* data no longer flowing */
46 } xfer_status;
47
48 /* forward declarations */
49 struct XferElement;
50 struct XMsgSource;
51 struct XMsg;
52
53 /*
54  * "Class" declaration
55  */
56
57 struct Xfer {
58     /* The current status of this transfer.  This is read-only, and 
59      * must only be accessed from the main thread or with status_mutex
60      * held. */
61     xfer_status status;
62
63     /* lock this while checking status in a thread
64      * other than the main thread */
65     GMutex *status_mutex;
66
67     /* and wait on this for status changes */
68     GCond *status_cond;
69
70     /* -- remaining fields are private -- */
71
72     gint refcount;
73
74     /* All transfer elements for this transfer, in order from
75      * source to destination.  This is initialized when the Xfer is
76      * created. */
77     GPtrArray *elements;
78
79     /* temporary string for a representation of this transfer */
80     char *repr;
81
82     /* GSource and queue for incoming messages */
83     struct XMsgSource *msg_source;
84     GAsyncQueue *queue;
85
86     /* Number of active elements remaining (a.k.a. the number of
87      * XMSG_DONE messages to expect) */
88     gint num_active_elements;
89 };
90
91 typedef struct Xfer Xfer;
92
93 /* Note that all functions must be called from the main thread unless
94  * otherwise noted */
95
96 /* Create a new Xfer object, which should later be freed with xfref_free.
97  *
98  * This function adds a reference to each element.  The caller should
99  * unreference the elements if it does not intend to use them directly.
100  * The Xfer returned has a refcount of one.
101  *
102  * @param elements: array of pointers to transfer elements, in order from source
103  *     to destination
104  * @param nelements: length of 'elements'
105  * @returns: new Xfer object
106  */
107 Xfer *xfer_new(struct XferElement **elements, unsigned int nelements);
108
109 /* Increase the reference count of a transfer.
110  *
111  * @param xfer: the transfer
112  */
113 void xfer_ref(Xfer *xfer);
114
115 /* Decrease the reference count of a transfer, possibly freeing it.  A running
116  * transfer (state neither XFER_INIT nor XFER_DONE) will not be freed.
117  *
118  * @param xfer: the transfer
119  */
120 void xfer_unref(Xfer *xfer);
121
122 /* Get a GSource which will produce events corresponding to messages from
123  * this transfer.  This is a "peek" operation, so the reference count for the
124  * GSource is not affected.  Note that the same GSource is returned on every
125  * call for a particular transfer.
126  *
127  * @returns: GSource object
128  */
129 GSource *xfer_get_source(Xfer *xfer);
130
131 /* Typedef for the callback to be set on the GSource returned from
132  * xfer_get_source.
133  */
134 typedef void (*XMsgCallback)(gpointer data, struct XMsg *msg, Xfer *xfer);
135
136 /* Queue a message for delivery via this transfer's GSource.  This can
137  * be called in any thread.
138  *
139  * @param xfer: the transfer
140  * @param msg: the message to queue
141  */
142 void xfer_queue_message(Xfer *xfer, struct XMsg *msg);
143
144 /* Get a representation of this transfer.  The string belongs to the transfer, and
145  * will be freed when the transfer is freed.
146  *
147  * @param xfer: the Xfer object
148  * @returns: statically allocated string
149  */
150 char *xfer_repr(Xfer *xfer);
151
152 /* Start a transfer.  This function will fail with an error message if it is
153  * unable to set up the transfer (e.g., if the elements cannot be connected
154  * correctly).
155  *
156  * @param xfer: the Xfer object
157  */
158 void xfer_start(Xfer *xfer);
159
160 /* Abort a running transfer.  This essentially tells the source to stop
161  * producing data and allows the remainder of the transfer to "drain".  Thus
162  * the transfer will signal its completion "normally" some time after
163  * xfer_cancel returns.  In particular, the state transitions will occur
164  * as follows:
165  *
166  * - XFER_RUNNING
167  * - xfer_cancel()  (note state may still be XFER_RUNNING on return)
168  * - XFER_CANCELLING
169  * - (individual elements' cancel() methods are invoked)
170  * - XFER_CANCELLED
171  * - (data drains from the transfer)
172  * - XFER_DONE
173  *
174  * This function can be called from any thread at any time.  It will return
175  * without blocking.
176  *
177  * @param xfer: the Xfer object
178  */
179 void xfer_cancel(Xfer *xfer);
180
181 /*
182  * Utilities
183  */
184
185 /* Wait for the xfer's state to become CANCELLED or DONE; this is useful to
186  * wait until a cancelletion is in progress before returning an EOF or
187  * otherwise handling a failure.  If you call this in the main thread, you'll
188  * be waiting for a while.
189  *
190  * @param xfer: the transfer object
191  * @returns: the new status (XFER_CANCELLED or XFER_DONE)
192  */
193 xfer_status wait_until_xfer_cancelled(Xfer *xfer);
194
195 /* Wait for the xfer's state to become anything but START; this is
196  * called *automatically* for every xfer_element_pull_buffer call, as the
197  * upstream element may not be running and ready for a pull just yet.  But
198  * the function may be useful in other places, too.
199  *
200  * @param xfer: the transfer object
201  * @returns: the new status (XFER_CANCELLED or XFER_DONE)
202  */
203 xfer_status wait_until_xfer_running(Xfer *xfer);
204
205 /* Send an XMSG_ERROR constructed with the given format and arguments, then
206  * cancel the transfer, then wait until the transfer is completely cancelled.
207  * This is the most common error-handling process for transfer elements.  All
208  * that remains to be done on return is to branch to the appropriate point in
209  * the cancellation-handling portion of the transfer.
210  *
211  * @param elt: the transfer element producing the error
212  * @param fmt: the format for the error message
213  * @param ...: arguments corresponding to the format
214  */
215 void xfer_cancel_with_error(struct XferElement *elt, const char *fmt, ...)
216         G_GNUC_PRINTF(2,3);
217
218 #endif /* XFER_H */