2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 2008 Zmanda Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library 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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 /* parent class for XferElement */
25 static GObjectClass *parent_class = NULL;
27 /* parent class for XferDest, XferFilter, and XferSource */
28 static XferElementClass *xfer_element_class = NULL;
30 /***********************
38 xe->output_mech = XFER_MECH_NONE;
39 xe->input_mech = XFER_MECH_NONE;
40 xe->upstream = xe->downstream = NULL;
41 xe->input_fd = xe->output_fd = -1;
46 xfer_element_setup_impl(
47 XferElement *elt G_GNUC_UNUSED)
52 xfer_element_start_impl(
53 XferElement *elt G_GNUC_UNUSED)
59 xfer_element_cancel_impl(
63 elt->cancelled = TRUE;
64 elt->expect_eof = expect_eof;
65 return elt->can_generate_eof;
69 xfer_element_pull_buffer_impl(
70 XferElement *elt G_GNUC_UNUSED,
71 size_t *size G_GNUC_UNUSED)
77 xfer_element_push_buffer_impl(
78 XferElement *elt G_GNUC_UNUSED,
79 gpointer buf G_GNUC_UNUSED,
80 size_t size G_GNUC_UNUSED)
85 xfer_element_repr_impl(
89 elt->repr = newvstrallocf(elt->repr, "<%s@%p>",
90 G_OBJECT_TYPE_NAME(G_OBJECT(elt)),
98 xfer_element_finalize(
101 XferElement *elt = XFER_ELEMENT(obj_self);
103 /* free the repr cache */
104 if (elt->repr) g_free(elt->repr);
107 G_OBJECT_CLASS(parent_class)->finalize(obj_self);
111 xfer_element_class_init(
112 XferElementClass * klass)
114 GObjectClass *goc = (GObjectClass*) klass;
116 klass->repr = xfer_element_repr_impl;
117 klass->setup = xfer_element_setup_impl;
118 klass->start = xfer_element_start_impl;
119 klass->cancel = xfer_element_cancel_impl;
120 klass->pull_buffer = xfer_element_pull_buffer_impl;
121 klass->push_buffer = xfer_element_push_buffer_impl;
123 goc->finalize = xfer_element_finalize;
125 klass->perl_class = NULL;
127 parent_class = g_type_class_peek_parent(klass);
128 xfer_element_class = klass;
132 xfer_element_get_type(void)
134 static GType type = 0;
136 if G_UNLIKELY(type == 0) {
137 static const GTypeInfo info = {
138 sizeof (XferElementClass),
139 (GBaseInitFunc) NULL,
140 (GBaseFinalizeFunc) NULL,
141 (GClassInitFunc) xfer_element_class_init,
142 (GClassFinalizeFunc) NULL,
143 NULL /* class_data */,
144 sizeof (XferElement),
146 (GInstanceInitFunc) xfer_element_init,
150 type = g_type_register_static (G_TYPE_OBJECT, "XferElement", &info,
151 (GTypeFlags)G_TYPE_FLAG_ABSTRACT);
165 if (elt) g_object_unref(elt);
172 return XFER_ELEMENT_GET_CLASS(elt)->repr(elt);
179 XFER_ELEMENT_GET_CLASS(elt)->setup(elt);
186 return XFER_ELEMENT_GET_CLASS(elt)->start(elt);
194 return XFER_ELEMENT_GET_CLASS(elt)->cancel(elt, expect_eof);
198 xfer_element_pull_buffer(
202 return XFER_ELEMENT_GET_CLASS(elt)->pull_buffer(elt, size);
206 xfer_element_push_buffer(
211 XFER_ELEMENT_GET_CLASS(elt)->push_buffer(elt, buf, size);
219 xfer_element_drain_by_pulling(
220 XferElement *upstream)
225 while ((buf =xfer_element_pull_buffer(upstream, &size))) {
231 xfer_element_drain_by_reading(
238 len = full_read(fd, buf, sizeof(buf));
239 if (len < sizeof(buf))
245 wait_until_xfer_cancelled(
248 xfer_status seen_status;
249 g_assert(xfer != NULL);
251 g_mutex_lock(xfer->status_mutex);
252 while (xfer->status != XFER_CANCELLED && xfer->status != XFER_DONE)
253 g_cond_wait(xfer->status_cond, xfer->status_mutex);
254 seen_status = xfer->status;
255 g_mutex_unlock(xfer->status_mutex);
261 xfer_element_handle_error(
269 g_assert(elt != NULL);
270 g_assert(elt->xfer != NULL);
272 msg = xmsg_new(elt, XMSG_ERROR, 0);
274 arglist_start(argp, fmt);
275 msg->message = g_strdup_vprintf(fmt, argp);
278 /* send the XMSG_ERROR */
279 xfer_queue_message(elt->xfer, msg);
281 /* cancel the transfer */
282 xfer_cancel(elt->xfer);
284 /* and wait for the cancellation to take effect */
285 wait_until_xfer_cancelled(elt->xfer);