Imported Upstream version 3.1.0
[debian/amanda] / device-src / device-queueing.c
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 #include "amanda.h"
22 #include "device-queueing.h"
23 #include "device.h"
24
25 producer_result_t device_read_producer(gpointer devicep,
26                                        queue_buffer_t *buffer,
27                                        size_t hint_size G_GNUC_UNUSED) {
28     Device* device;
29
30     device = (Device*) devicep;
31     g_assert(IS_DEVICE(device));
32
33     buffer->offset = 0;
34     for (;;) {
35         int result, read_size;
36         read_size = buffer->alloc_size;
37         result = device_read_block(device, buffer->data, &read_size);
38         if (result > 0) {
39             buffer->data_size = read_size;
40             return PRODUCER_MORE;
41         } else if (result == 0) {
42             /* unfortunately, the best "memory" we have of needing a larger
43              * block size is the next time this buffer comes around, and even
44              * this is incomplete as buffers may be resized periodically.  So
45              * we'll end up calling read_block with small buffers more often
46              * than strictly necessary. */
47             buffer->data = realloc(buffer->data, read_size);
48             buffer->alloc_size = read_size;
49         } else if (device->is_eof) {
50             return PRODUCER_FINISHED;
51         } else {
52             buffer->data_size = 0;
53             return PRODUCER_ERROR;
54         }
55     }
56 }
57
58 ssize_t device_write_consumer(gpointer devicep, queue_buffer_t *buffer) {
59     Device* device;
60     size_t write_size;
61     gsize block_size;
62
63     device = DEVICE(devicep);
64
65     block_size = device->block_size;
66     write_size = MIN(buffer->data_size, block_size);
67
68     /* we assume that the queueing module is providing us with
69      * appropriately-sized blocks until the last block. */
70     if (device_write_block(device, write_size,
71                            buffer->data + buffer->offset)) {
72         /* Success! */
73         return write_size;
74     } else {
75         /* Nope, really an error. */
76         return -1;
77     }
78 }
79