1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-19 10:03:58 +03:00

Allow us to "lock" printer tdb entries in memory to stop them being

re-used as cache.
Jeremy.
(This used to be commit 6f901e479dd7a0b9d1395aad5b8ef028c0514fec)
This commit is contained in:
Jeremy Allison 2002-08-27 20:15:35 +00:00
parent 4896421e30
commit 16413f2d9d

View File

@ -132,11 +132,13 @@ static pid_t local_pid;
static int get_queue_status(int, print_status_struct *);
/* There can be this many printing tdb's open, plus any locked ones. */
#define MAX_PRINT_DBS_OPEN 1
struct tdb_print_db {
struct tdb_print_db *next, *prev;
TDB_CONTEXT *tdb;
int locked;
fstring printer_name;
};
@ -149,7 +151,7 @@ static struct tdb_print_db *print_db_head;
static struct tdb_print_db *get_print_db_byname(const char *printername)
{
struct tdb_print_db *p, *last_entry;
struct tdb_print_db *p = NULL, *last_entry = NULL;
int num_open = 0;
pstring printdb_path;
@ -161,20 +163,28 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
num_open++;
last_entry = p;
}
/* Not found. */
if (num_open >= MAX_PRINT_DBS_OPEN) {
/* Recycle the last entry. */
/* Try and recycle the last entry. */
DLIST_PROMOTE(print_db_head, last_entry);
if (print_db_head->tdb) {
if (tdb_close(print_db_head->tdb)) {
DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
print_db_head->printer_name ));
return NULL;
for (p = print_db_head; p; p = p->next) {
if (p->locked)
continue;
if (p->tdb) {
if (tdb_close(print_db_head->tdb)) {
DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
print_db_head->printer_name ));
return NULL;
}
ZERO_STRUCTP(p);
DLIST_PROMOTE(print_db_head, p);
}
}
p = print_db_head;
ZERO_STRUCTP(p);
} else {
}
if (!p) {
/* Create one. */
p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
if (!p) {
@ -204,6 +214,30 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
return p;
}
/****************************************************************************
Lock a pdb entry by string.
****************************************************************************/
static int pdb_entry_lock(struct tdb_print_db *pdb, char *key)
{
if (pdb->locked == 0) {
if (tdb_lock_bystring(pdb->tdb, key) == -1)
return -1;
}
pdb->locked++;
}
/****************************************************************************
Unlock a pdb entry by string.
****************************************************************************/
static void pdb_entry_unlock(struct tdb_print_db *pdb, char *key)
{
pdb->locked--;
if (pdb->locked == 0)
tdb_unlock_bystring(pdb->tdb, key);
}
/****************************************************************************
Initialise the printing backend. Called once at startup.
Does not survive a fork
@ -235,12 +269,15 @@ BOOL print_backend_init(void)
pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
continue;
tdb_lock_bystring(pdb->tdb, sversion);
if (pdb_entry_lock(pdb, sversion) == -1) {
DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
return False;
}
if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
}
tdb_unlock_bystring(pdb->tdb, sversion);
pdb_entry_unlock(pdb, sversion);
}
/* select the appropriate printing interface... */
@ -746,7 +783,10 @@ static void print_queue_update(int snum)
/* Lock the queue for the database update */
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
tdb_lock_bystring(pdb->tdb, keystr);
if (pdb_entry_lock(pdb, keystr) == -1) {
DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
return;
}
/*
* Ensure that no one else got in here.
@ -758,7 +798,7 @@ static void print_queue_update(int snum)
/*
* Someone else is doing the update, exit.
*/
tdb_unlock_bystring(pdb->tdb, keystr);
pdb_entry_unlock(pdb, keystr);
return;
}
@ -774,7 +814,7 @@ static void print_queue_update(int snum)
* the update.
*/
tdb_unlock_bystring(pdb->tdb, keystr);
pdb_entry_unlock(pdb, keystr);
/*
* Update the cache time FIRST ! Stops others even
@ -1335,7 +1375,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
fstrcpy(pjob.queuename, lp_const_servicename(snum));
/* lock the database */
tdb_lock_bystring(pdb->tdb, "INFO/nextjob");
if (pdb_entry_lock(pdb, "INFO/nextjob") == -1) {
DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername ));
return (uint32)-1;
}
next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob");
if (next_jobid == -1)
@ -1378,7 +1421,7 @@ to open spool file %s.\n", pjob.filename));
pjob_store(snum, jobid, &pjob);
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
pdb_entry_unlock(pdb, "INFO/nextjob");
/*
* If the printer is marked as postscript output a leading
@ -1397,7 +1440,7 @@ to open spool file %s.\n", pjob.filename));
if (jobid != -1)
pjob_delete(snum, jobid);
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
pdb_entry_unlock(pdb, "INFO/nextjob");
DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
return -1;