Imported Upstream version 3.1.0
[debian/amanda] / common-src / queueing.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 #ifndef QUEUEING_H
22 #define QUEUEING_H
23
24 /* This file contains the code for fast threaded reading and writing to/from
25  * media, for devices that don't require any special handling. Some
26  * devices (e.g., CD-ROM) may use a different method for bulk reads or
27  * writes. */
28
29 #include "amanda.h"
30 #include <glib.h>
31
32 #define DEFAULT_MAX_BUFFER_MEMORY (1*1024*1024)
33
34 typedef enum {
35     STREAMING_REQUIREMENT_NONE,
36     STREAMING_REQUIREMENT_DESIRED,
37     STREAMING_REQUIREMENT_REQUIRED
38 } StreamingRequirement;
39
40 /* Valid data in this structure starts at data + offset, and has size
41  * data_size. Allocation starts at data and has size alloc_size. */
42 typedef struct {
43     char *data;
44     size_t alloc_size;
45     size_t data_size;
46     size_t offset;
47 } queue_buffer_t;
48
49 void free_buffer(queue_buffer_t*);
50
51 typedef enum {
52     PRODUCER_MORE,     /* Means the producer should be run again. */
53     PRODUCER_FINISHED, /* Means that no error occured, but the
54                           producer should not be run again. */
55     PRODUCER_ERROR     /* Means an error occured, and the producer
56                           should not be run again. */
57 } producer_result_t;
58
59 typedef enum {
60     QUEUE_SUCCESS = 0,
61     QUEUE_PRODUCER_ERROR = 1 << 0,
62     QUEUE_CONSUMER_ERROR = 1 << 1,
63     QUEUE_INTERNAL_ERROR = 1 << 2
64 } queue_result_flags;
65
66 /* The producer takes the given buffer (which is not itself NULL, but may contain
67  * a NULL data segment), and fills it with data. The producer can allocate or
68  * reallocate the buffer's 'data' element as necessary; the queueing system will
69  * free it when necessary. The result of the production operation is specified in
70  * the return value, but if the buffer is left without data, then that is
71  * interpreted as PRODUCER_ERROR. For optimal performance, the producer should
72  * supply exactly hint_size bytes of data in each call, but this is not required.
73  *
74  * The consumer is given a buffer (which will not be NULL, nor contain a NULL data
75  * segment), and is expected to process some or all of the data in that buffer. If
76  * there is a problem consuming data (such that no further data can be consumed),
77  * the consumer may return -1. Otherwise, the consumer should return the number of
78  * bytes actually consumed.  If an error occurs, it should return -1, regardless
79  * of the number of bytes consumed.  The queueing framework will ensure that all
80  * blocks have at least hint_size bytes, except the last.  For optimal
81  * performance, the consumer should consume the entire buffer at each call, but
82  * this is not required.
83  *
84  * Note that the handling of the queue_buffer_t is different between the two
85  * functions: The producer should update queue_buffer_t as necessary to corespond
86  * to read data, while the consumer should leave the queue_buffer_t unadjusted:
87  * The queueing framework will invalidate data in the buffer according to the
88  * return value of the consumer.*/
89
90 typedef producer_result_t (* ProducerFunctor)(gpointer user_data,
91                                               queue_buffer_t* buffer,
92                                               size_t hint_size);
93 typedef ssize_t (* ConsumerFunctor)(gpointer user_data,
94                                 queue_buffer_t* buffer);
95
96
97 /* These functions make the magic happen. The first one assumes
98    reasonable defaults, the second one provides more options.
99    % producer           : A function that provides data to write.
100    % producer_user_data : A pointer to pass to that function.
101    % consumer           : A function that writes data out.
102    % consumer_user_data : A pointer to pass to that function.
103    % block_size         : Size of chunks to write out to consumer. If
104                           nonpositive, data will be written in
105                           variable-sized chunks.
106    % max_memory         : Amount of memory to be used for buffering.
107                           (default is DEFAULT_MAX_BUFFER_MEMORY).
108    % streaming_mode     : Describes streaming mode.
109          STREAMING_REQUIREMENT_NONE:     Data will be written as fast
110                                          as possible. No prebuffering
111                                          will be done.
112          STREAMING_REQUIREMENT_DESIRED:  max_memory bytes of data will
113                                          be prebuffered, and if the
114                                          buffer ever empties, no data
115                                          will be written until it
116                                          fills again.
117          STREAMING_REQUIREMENT_REQUIRED: max_memory bytes of data will
118                                          be prebuffered, and
119                                          thereafter data will be
120                                          written as fast as possible.
121 */
122 gboolean
123 do_consumer_producer_queue(ProducerFunctor producer,
124                            gpointer producer_user_data,
125                            ConsumerFunctor consumer,
126                            gpointer consumer_user_data);
127 queue_result_flags
128 do_consumer_producer_queue_full(ProducerFunctor producer,
129                                 gpointer producer_user_data,
130                                 ConsumerFunctor consumer,
131                                 gpointer consumer_user_data,
132                                 size_t block_size,
133                                 size_t max_memory,
134                                 StreamingRequirement streaming_mode);
135
136 /* Some commonly-useful producers and consumers.*/
137
138 /* These functions will call read() or write() respectively. The user
139    data should be a pointer to an queue_fd_t, with fd set to the device
140    descriptor and errmsg set to NULL. */
141
142 typedef struct {
143     int fd;
144     char *errmsg;
145 } queue_fd_t;
146
147 queue_fd_t *queue_fd_new(int fd, char *errmsg);
148 int queue_fd_fd(queue_fd_t *queue_fd);
149 char *queue_fd_errmsg(queue_fd_t *queue_fd);
150
151 producer_result_t fd_read_producer(gpointer queue_fd, queue_buffer_t *buffer,
152                                    size_t hint_size);
153 ssize_t fd_write_consumer(gpointer queue_fd, queue_buffer_t *buffer);
154
155
156
157 #endif /* QUEUEING_H */