X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=xfer-src%2Fxfer-element.c;h=37e3377de8cea3bee41eca649318a71608bec55d;hb=9a2cb1de801e3447b76f372bdb4e5dea743e1b6d;hp=df429fa47eb3a58f850a2ad44b361d13de02122b;hpb=d5853102f67d85d8e169f9dbe973ad573306c215;p=debian%2Famanda diff --git a/xfer-src/xfer-element.c b/xfer-src/xfer-element.c index df429fa..37e3377 100644 --- a/xfer-src/xfer-element.c +++ b/xfer-src/xfer-element.c @@ -1,6 +1,6 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -19,8 +19,8 @@ * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com */ -#include "amxfer.h" #include "amanda.h" +#include "amxfer.h" /* parent class for XferElement */ static GObjectClass *parent_class = NULL; @@ -39,7 +39,7 @@ xfer_element_init( xe->output_mech = XFER_MECH_NONE; xe->input_mech = XFER_MECH_NONE; xe->upstream = xe->downstream = NULL; - xe->input_fd = xe->output_fd = -1; + xe->_input_fd = xe->_output_fd = -1; xe->repr = NULL; } @@ -50,6 +50,16 @@ xfer_element_setup_impl( return TRUE; /* success */ } +static gboolean +xfer_element_set_size_impl( + XferElement *elt G_GNUC_UNUSED, + gint64 size G_GNUC_UNUSED) +{ + elt->size = size; + + return TRUE; /* success */ +} + static gboolean xfer_element_start_impl( XferElement *elt G_GNUC_UNUSED) @@ -108,10 +118,20 @@ xfer_element_finalize( GObject * obj_self) { XferElement *elt = XFER_ELEMENT(obj_self); + gint fd; /* free the repr cache */ if (elt->repr) g_free(elt->repr); + /* close up the input/output file descriptors, being careful to do so + * atomically, and making any errors doing so into mere warnings */ + fd = xfer_element_swap_input_fd(elt, -1); + if (fd != -1 && close(fd) != 0) + g_warning("error closing fd %d: %s", fd, strerror(errno)); + fd = xfer_element_swap_output_fd(elt, -1); + if (fd != -1 && close(fd) != 0) + g_warning("error closing fd %d: %s", fd, strerror(errno)); + /* chain up */ G_OBJECT_CLASS(parent_class)->finalize(obj_self); } @@ -124,6 +144,7 @@ xfer_element_class_init( klass->repr = xfer_element_repr_impl; klass->setup = xfer_element_setup_impl; + klass->set_size = xfer_element_set_size_impl; klass->start = xfer_element_start_impl; klass->cancel = xfer_element_cancel_impl; klass->pull_buffer = xfer_element_pull_buffer_impl; @@ -189,6 +210,14 @@ xfer_element_setup( return XFER_ELEMENT_GET_CLASS(elt)->setup(elt); } +gboolean +xfer_element_set_size( + XferElement *elt, + gint64 size) +{ + return XFER_ELEMENT_GET_CLASS(elt)->set_size(elt, size); +} + gboolean xfer_element_start( XferElement *elt) @@ -209,11 +238,15 @@ xfer_element_pull_buffer( XferElement *elt, size_t *size) { + xfer_status status; /* Make sure that the xfer is running before calling upstream's * pull_buffer method; this avoids a race condition where upstream * hasn't finished its xfer_element_start yet, and isn't ready for * a pull */ - if (elt->xfer->status == XFER_START) + g_mutex_lock(elt->xfer->status_mutex); + status = elt->xfer->status; + g_mutex_unlock(elt->xfer->status_mutex); + if (status == XFER_START) wait_until_xfer_running(elt->xfer); return XFER_ELEMENT_GET_CLASS(elt)->pull_buffer(elt, size); @@ -242,7 +275,7 @@ xfer_element_get_mech_pairs( */ void -xfer_element_drain_by_pulling( +xfer_element_drain_buffers( XferElement *upstream) { gpointer buf; @@ -254,7 +287,7 @@ xfer_element_drain_by_pulling( } void -xfer_element_drain_by_reading( +xfer_element_drain_fd( int fd) { size_t len;