summaryrefslogtreecommitdiff
path: root/source3/printing/print_cups.c
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@suse.de>2010-12-19 19:52:08 +0100
committerJeremy Allison <jra@samba.org>2011-01-07 15:37:39 -0800
commit04248c2cfaa5a1728ef58fc8ca231fd1309ca694 (patch)
tree81e3be76291d3fdbf5f1e29869c6ef82f7305193 /source3/printing/print_cups.c
parent3a14c97459ea21f4a3ecefabfd676cb9839a162f (diff)
downloadsamba-04248c2cfaa5a1728ef58fc8ca231fd1309ca694.tar.gz
samba-04248c2cfaa5a1728ef58fc8ca231fd1309ca694.tar.bz2
samba-04248c2cfaa5a1728ef58fc8ca231fd1309ca694.zip
s3-printing: reload shares after pcap cache fill
Since commit eada8f8a, updates to the cups pcap cache are performed asynchronously - cups_cache_reload() forks a child process to request cups printer information and notify the parent smbd on completion. Currently printer shares are reloaded immediately following the call to cups_cache_reload(), this occurs prior to smbd receiving new cups pcap information from the child process. Such behaviour can result in stale print shares as outlined in bug 7836. This fix ensures print shares are only reloaded after new pcap data has been received. Pair-Programmed-With: Lars Müller <lars@samba.org>
Diffstat (limited to 'source3/printing/print_cups.c')
-rw-r--r--source3/printing/print_cups.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index a85fba8997..8c023ddb30 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -449,13 +449,22 @@ static bool cups_pcap_load_async(struct tevent_context *ev,
_exit(0);
}
+struct cups_async_cb_args {
+ int pipe_fd;
+ struct event_context *event_ctx;
+ struct messaging_context *msg_ctx;
+ void (*post_cache_fill_fn)(struct event_context *,
+ struct messaging_context *);
+};
+
static void cups_async_callback(struct event_context *event_ctx,
struct fd_event *event,
uint16 flags,
void *p)
{
TALLOC_CTX *frame = talloc_stackframe();
- int fd = *(int *)p;
+ struct cups_async_cb_args *cb_args = (struct cups_async_cb_args *)p;
+ int fd = cb_args->pipe_fd;
struct pcap_cache *tmp_pcap_cache = NULL;
DEBUG(5,("cups_async_callback: callback received for printer data. "
@@ -549,28 +558,43 @@ static void cups_async_callback(struct event_context *event_ctx,
/* And the systemwide pcap cache. */
pcap_cache_replace(local_pcap_copy);
+
+ /* Caller may have requested post cache fill callback */
+ if (cb_args->post_cache_fill_fn != NULL) {
+ cb_args->post_cache_fill_fn(cb_args->event_ctx,
+ cb_args->msg_ctx);
+ }
} else {
DEBUG(2,("cups_async_callback: failed to read a new "
"printer list\n"));
}
close(fd);
- TALLOC_FREE(p);
+ TALLOC_FREE(cb_args);
TALLOC_FREE(cache_fd_event);
}
bool cups_cache_reload(struct tevent_context *ev,
- struct messaging_context *msg_ctx)
+ struct messaging_context *msg_ctx,
+ void (*post_cache_fill_fn)(struct tevent_context *,
+ struct messaging_context *))
{
- int *p_pipe_fd = TALLOC_P(NULL, int);
+ struct cups_async_cb_args *cb_args;
+ int *p_pipe_fd;
- if (!p_pipe_fd) {
+ cb_args = TALLOC_P(NULL, struct cups_async_cb_args);
+ if (cb_args == NULL) {
return false;
}
+ cb_args->post_cache_fill_fn = post_cache_fill_fn;
+ cb_args->event_ctx = ev;
+ cb_args->msg_ctx = msg_ctx;
+ p_pipe_fd = &cb_args->pipe_fd;
*p_pipe_fd = -1;
/* Set up an async refresh. */
if (!cups_pcap_load_async(ev, msg_ctx, p_pipe_fd)) {
+ talloc_free(cb_args);
return false;
}
if (!local_pcap_copy) {
@@ -582,7 +606,7 @@ bool cups_cache_reload(struct tevent_context *ev,
cups_async_callback(ev, NULL,
EVENT_FD_READ,
- (void *)p_pipe_fd);
+ (void *)cb_args);
if (!local_pcap_copy) {
return false;
}
@@ -599,10 +623,10 @@ bool cups_cache_reload(struct tevent_context *ev,
NULL, *p_pipe_fd,
EVENT_FD_READ,
cups_async_callback,
- (void *)p_pipe_fd);
+ (void *)cb_args);
if (!cache_fd_event) {
close(*p_pipe_fd);
- TALLOC_FREE(p_pipe_fd);
+ TALLOC_FREE(cb_args);
return false;
}
}