From: Martin Mares Date: Tue, 2 Sep 2008 20:07:18 +0000 (+0200) Subject: Automatic tying of fastbufs to resources. X-Git-Tag: v5.0~74^2~42 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=a45646a634b71708f5bc4277868c60e80daaa84c;p=libucw.git Automatic tying of fastbufs to resources. --- diff --git a/ucw/Makefile b/ucw/Makefile index 4ff774e4..6f076ed7 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -34,7 +34,7 @@ LIBUCW_MODS= \ bbuf gary \ getopt \ strtonum \ - respool trans + respool trans res-fd res-mem LIBUCW_MAIN_INCLUDES= \ lib.h log.h threads.h \ diff --git a/ucw/doc/fastbuf.txt b/ucw/doc/fastbuf.txt index d94fffe9..86ab55d9 100644 --- a/ucw/doc/fastbuf.txt +++ b/ucw/doc/fastbuf.txt @@ -18,6 +18,12 @@ inbetween and remember that the file position reported by @btell() points after the flushed buffer, which is not necessarily the same as after the data you've really read. +Most fastbuf back-ends also participate in the libucw resource management system. +If you have a resource pool active, newly created fastbufs are automatically tied +to resources in the pool, so when the pool gets cleaned up, the fastbufs are +freed, too. The bclose() function is still available and it removes the tie +as needed. + .Back-ends: - <> - <> diff --git a/ucw/fastbuf.c b/ucw/fastbuf.c index 9ba01ef4..de38b277 100644 --- a/ucw/fastbuf.c +++ b/ucw/fastbuf.c @@ -9,6 +9,7 @@ #include "ucw/lib.h" #include "ucw/fastbuf.h" +#include "ucw/respool.h" #include #include @@ -20,6 +21,8 @@ void bclose(struct fastbuf *f) bflush(f); if (f->close) f->close(f); + if (f->res) + res_drop(f->res); } } @@ -202,3 +205,40 @@ bfilesize(struct fastbuf *f) bsetpos(f, pos); return len; } + +/* Resources */ + +static void +fb_res_detach(struct resource *r) +{ + struct fastbuf *f = r->priv; + f->res = NULL; +} + +static void +fb_res_free(struct resource *r) +{ + struct fastbuf *f = r->priv; + f->res = NULL; + bclose(f); +} + +static void +fb_res_dump(struct resource *r) +{ + struct fastbuf *f = r->priv; + printf(" name=%s", f->name); +} + +static const struct res_class fb_res_class = { + .name = "fastbuf", + .detach = fb_res_detach, + .dump = fb_res_dump, + .free = fb_res_free, +}; + +void +fb_tie(struct fastbuf *f) +{ + f->res = res_new(&fb_res_class, f); +} diff --git a/ucw/fastbuf.h b/ucw/fastbuf.h index 2c1c1a10..6e3b2626 100644 --- a/ucw/fastbuf.h +++ b/ucw/fastbuf.h @@ -139,13 +139,18 @@ struct fastbuf { void (*close)(struct fastbuf *); /* Close the stream */ int (*config)(struct fastbuf *, uns, int); /* Configure the stream */ int can_overwrite_buffer; /* Can the buffer be altered? 0=never, 1=temporarily, 2=permanently */ + struct resource *res; /* The fastbuf can be tied to a resource pool */ }; +void fb_tie(struct fastbuf *b); /* Tie fastbuf to a resource if there is an active pool */ + /*** * === Fastbuf on files [[fbparam]] * * If you want to use fastbufs to access files, you can choose one of several * back-ends and set their parameters. + * + * All file fastbufs are tied to resources automatically. ***/ /** @@ -292,6 +297,8 @@ void bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file); * * The `fblim` back-end reads from a file handle, but at most a given * number of bytes. This is frequently used for reading from sockets. + * + * All such fastbufs are tied to resources automatically. ***/ struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit); /** Create a fastbuf which reads at most @limit bytes from @fd. **/ @@ -306,6 +313,8 @@ struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit); /** Create a f * First, you use @fbmem_create() to create the stream and the fastbuf * used for writing to it. Then you can call @fbmem_clone_read() to get * an arbitrary number of fastbuf for reading from the stream. + * + * All in-memory fastbufs are tied to resources automatically. ***/ struct fastbuf *fbmem_create(uns blocksize); /** Create stream and return its writing fastbuf. **/ @@ -327,7 +336,8 @@ struct fastbuf *fbmem_clone_read(struct fastbuf *f); /** Given a writing fastbuf * of the buffer temporarily. In this case, set @can_overwrite as described * in <>. If you do not care, keep @can_overwrite zero. * - * It is not possible to close this fastbuf. + * It is not possible to close this fastbuf. This implies that no tying to + * resources takes place. */ void fbbuf_init_read(struct fastbuf *f, byte *buffer, uns size, uns can_overwrite); @@ -339,7 +349,8 @@ void fbbuf_init_read(struct fastbuf *f, byte *buffer, uns size, uns can_overwrit * Data are written directly into the buffer, so it is not necessary to call @bflush() * at any moment. * - * It is not possible to close this fastbuf. + * It is not possible to close this fastbuf. This implies that no tying to + * resources takes place. */ void fbbuf_init_write(struct fastbuf *f, byte *buffer, uns size); @@ -356,6 +367,8 @@ static inline uns fbbuf_count_written(struct fastbuf *f) /** Calculates, how man * size and it is expanded to accomodate all data. * * At every moment, you can use `fastbuf->buffer` to gain access to the stream. + * + * All fastbufs of this type are tied to resources automatically. ***/ struct fastbuf *fbgrow_create(unsigned basic_size); /** Create the growing buffer pre-allocated to @basic_size bytes. **/ @@ -376,7 +389,8 @@ struct fbpool { /** Structure for fastbufs & mempools. **/ }; /** - * Initialize a new `fbpool`. The structure is allocated by the caller. + * Initialize a new `fbpool`. The structure is allocated by the caller, + * so bclose() should not be called and no resource tying takes place. **/ void fbpool_init(struct fbpool *fb); /** Initialize a new mempool fastbuf. **/ /** @@ -411,6 +425,8 @@ void *fbpool_end(struct fbpool *fb); * * Please note that initialization of the clones is not thread-safe, * so you have to serialize it yourself. + * + * The atomic fastbufs are tied to resources automatically. ***/ struct fb_atomic { diff --git a/ucw/fb-atomic.c b/ucw/fb-atomic.c index 32c9ca9b..2283cee5 100644 --- a/ucw/fb-atomic.c +++ b/ucw/fb-atomic.c @@ -129,6 +129,7 @@ fbatomic_open(const char *name, struct fastbuf *master, uns bufsize, int record_ f->name = af->name; f->spout = fbatomic_spout; f->close = fbatomic_close; + fb_tie(f); return f; } diff --git a/ucw/fb-direct.c b/ucw/fb-direct.c index 1e2dfd89..71e7351b 100644 --- a/ucw/fb-direct.c +++ b/ucw/fb-direct.c @@ -308,6 +308,7 @@ fbdir_open_fd_internal(int fd, const char *name, struct asio_queue *q, uns buffe f->close = fbdir_close; f->config = fbdir_config; f->can_overwrite_buffer = 2; + fb_tie(f); return f; } diff --git a/ucw/fb-file.c b/ucw/fb-file.c index 3eb2996f..fff44378 100644 --- a/ucw/fb-file.c +++ b/ucw/fb-file.c @@ -244,6 +244,7 @@ bfdopen_internal(int fd, const char *name, uns buflen) f->close = bfd_close; f->config = bfd_config; f->can_overwrite_buffer = 2; + fb_tie(f); return f; } diff --git a/ucw/fb-grow.c b/ucw/fb-grow.c index e1da0107..7d4a8f84 100644 --- a/ucw/fb-grow.c +++ b/ucw/fb-grow.c @@ -80,6 +80,7 @@ fbgrow_create(unsigned basic_size) b->seek = fbgrow_seek; b->close = fbgrow_close; b->can_overwrite_buffer = 1; + fb_tie(b); return b; } diff --git a/ucw/fb-limfd.c b/ucw/fb-limfd.c index 7e30f6a2..4e7d406b 100644 --- a/ucw/fb-limfd.c +++ b/ucw/fb-limfd.c @@ -55,6 +55,7 @@ bopen_limited_fd(int fd, uns buflen, uns limit) f->refill = bfl_refill; f->close = bfl_close; f->can_overwrite_buffer = 2; + fb_tie(f); return f; } diff --git a/ucw/fb-mem.c b/ucw/fb-mem.c index 1acb38f6..a100d481 100644 --- a/ucw/fb-mem.c +++ b/ucw/fb-mem.c @@ -162,6 +162,7 @@ fbmem_create(unsigned blocksize) f->name = ""; f->spout = fbmem_spout; f->close = fbmem_close; + fb_tie(f); return f; } @@ -180,6 +181,7 @@ fbmem_clone_read(struct fastbuf *b) f->seek = fbmem_seek; f->close = fbmem_close; f->can_overwrite_buffer = 1; + fb_tie(f); return f; } diff --git a/ucw/fb-mmap.c b/ucw/fb-mmap.c index 747b4286..25209721 100644 --- a/ucw/fb-mmap.c +++ b/ucw/fb-mmap.c @@ -189,6 +189,7 @@ bfmmopen_internal(int fd, const char *name, uns mode) f->seek = bfmm_seek; f->close = bfmm_close; f->config = bfmm_config; + fb_tie(f); return f; } diff --git a/ucw/fb-socket.c b/ucw/fb-socket.c index dce8fffd..d90f7e7c 100644 --- a/ucw/fb-socket.c +++ b/ucw/fb-socket.c @@ -125,6 +125,7 @@ fbsock_create(struct fbsock_params *p) f->spout = fbs_spout; f->close = fbs_close; f->can_overwrite_buffer = 1; + fb_tie(f); return f; }