Index: source3/printing/print_cups.c =================================================================== --- source3/printing/print_cups.c.orig +++ source3/printing/print_cups.c @@ -440,13 +440,19 @@ static bool cups_pcap_load_async(int *pf _exit(0); } +struct cups_async_cb_args { + int pipe_fd; + void (*post_cache_fill_fn)(void); +}; + 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. " @@ -540,27 +546,34 @@ static void cups_async_callback(struct e /* 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) + cb_args->post_cache_fill_fn(); } 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(void) +bool cups_cache_reload(void (*post_cache_fill_fn)(void)) { - 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) return false; - } - + cb_args->post_cache_fill_fn = post_cache_fill_fn; + p_pipe_fd = &cb_args->pipe_fd; *p_pipe_fd = -1; /* Set up an async refresh. */ if (!cups_pcap_load_async(p_pipe_fd)) { + talloc_free(cb_args); return false; } if (!local_pcap_copy) { @@ -573,7 +586,7 @@ bool cups_cache_reload(void) cups_async_callback(smbd_event_context(), NULL, EVENT_FD_READ, - (void *)p_pipe_fd); + (void *)cb_args); if (!local_pcap_copy) { return false; } @@ -590,10 +603,10 @@ bool cups_cache_reload(void) 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; } } Index: source3/printing/pcap.c =================================================================== --- source3/printing/pcap.c.orig +++ source3/printing/pcap.c @@ -125,13 +125,14 @@ void pcap_cache_replace(const struct pca } } -void pcap_cache_reload(void) +void pcap_cache_reload(void (*post_cache_fill_fn)(void)) { const char *pcap_name = lp_printcapname(); bool pcap_reloaded = False; struct pcap_cache *tmp_cache = NULL; XFILE *pcap_file; char *pcap_line; + bool post_cache_fill_fn_handled = false; DEBUG(3, ("reloading printcap cache\n")); @@ -146,7 +147,12 @@ void pcap_cache_reload(void) #ifdef HAVE_CUPS if (strequal(pcap_name, "cups")) { - pcap_reloaded = cups_cache_reload(); + pcap_reloaded = cups_cache_reload(post_cache_fill_fn); + /* + * cups_cache_reload() is async and calls post_cache_fill_fn() + * on successful completion + */ + post_cache_fill_fn_handled = true; goto done; } #endif @@ -244,6 +250,8 @@ done: if (pcap_reloaded) pcap_cache_destroy_specific(&tmp_cache); + if (post_cache_fill_fn_handled == false) + post_cache_fill_fn(); else { pcap_cache_destroy_specific(&pcap_cache); pcap_cache = tmp_cache; Index: source3/smbd/server.c =================================================================== --- source3/smbd/server.c.orig +++ source3/smbd/server.c @@ -689,9 +689,9 @@ static void smbd_parent_loop(struct smbd /* NOTREACHED return True; */ } -/**************************************************************************** - Reload printers -**************************************************************************/ +/*************************************************************************** +purge stale printers and reload from pre-populated pcap cache +***************************************************************************/ void reload_printers(void) { int snum; @@ -699,9 +699,9 @@ void reload_printers(void) int pnum = lp_servicenumber(PRINTERS_NAME); const char *pname; - pcap_cache_reload(); + SMB_ASSERT(pcap_cache_loaded()); - /* remove stale printers */ + DEBUG(10, ("reloading printer services from pcap cache\n")); for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME or non-autoloaded printers */ if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) && @@ -748,7 +748,7 @@ bool reload_services(bool test) ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True); - reload_printers(); + pcap_cache_reload(&reload_printers); /* perhaps the config filename is now set */ if (!test) Index: source3/printing/load.c =================================================================== --- source3/printing/load.c.orig +++ source3/printing/load.c @@ -53,12 +53,11 @@ static void add_auto_printers(void) } /*************************************************************************** -load automatic printer services +load automatic printer services from pre-populated pcap cache ***************************************************************************/ void load_printers(void) { - if (!pcap_cache_loaded()) - pcap_cache_reload(); + SMB_ASSERT(pcap_cache_loaded()); add_auto_printers(); Index: source3/include/proto.h =================================================================== --- source3/include/proto.h.orig +++ source3/include/proto.h @@ -4870,7 +4870,7 @@ void pcap_cache_destroy_specific(struct bool pcap_cache_add(const char *name, const char *comment); bool pcap_cache_loaded(void); void pcap_cache_replace(const struct pcap_cache *cache); -void pcap_cache_reload(void); +void pcap_cache_reload(void (*post_cache_fill_fn)(void)); bool pcap_printername_ok(const char *printername); void pcap_printer_fn_specific(const struct pcap_cache *, void (*fn)(const char *, const char *, void *), void *); void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *); @@ -4881,7 +4881,7 @@ bool aix_cache_reload(void); /* The following definitions come from printing/print_cups.c */ -bool cups_cache_reload(void); +bool cups_cache_reload(void (*post_cache_fill_fn)(void)); bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer); /* The following definitions come from printing/print_generic.c */ Index: source3/web/swat.c =================================================================== --- source3/web/swat.c.orig +++ source3/web/swat.c @@ -490,7 +490,7 @@ static int save_reload(int snum) return 0; } iNumNonAutoPrintServices = lp_numservices(); - load_printers(); + pcap_cache_reload(&load_printers); return 1; } @@ -1434,7 +1434,7 @@ const char *lang_msg_rotate(TALLOC_CTX * load_config(True); load_interfaces(); iNumNonAutoPrintServices = lp_numservices(); - load_printers(); + pcap_cache_reload(&load_printers); cgi_setup(get_dyn_SWATDIR(), !demo_mode);