/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2001-2003 * Sleepycat Software. All rights reserved. * * $Id: ex_rq_master.c,v 1.2 2004/03/30 01:23:18 jtownsen Exp $ */ #include #include #include #include #include #include #include "ex_repquote.h" static void *master_loop __P((void *)); #define BUFSIZE 1024 int domaster(dbenv, progname) DB_ENV *dbenv; const char *progname; { int ret; thread interface_thr; #ifndef _WIN32 int t_ret; pthread_attr_t attr; /* Spawn off a thread to handle the basic master interface. */ if ((ret = pthread_attr_init(&attr)) != 0 && (ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) != 0) goto err; #endif if ((ret = thread_create(&interface_thr, &attr, master_loop, (void *)dbenv)) != 0) goto err; err: #ifndef _WIN32 if ((t_ret = pthread_attr_destroy(&attr)) != 0 && ret == 0) ret = t_ret; #endif COMPQUIET(progname, NULL); return (ret); } static void * master_loop(dbenvv) void *dbenvv; { DB *dbp; DB_ENV *dbenv; DB_TXN *txn; DBT key, data; char buf[BUFSIZE], *rbuf; int ret; dbp = NULL; txn = NULL; dbenv = (DB_ENV *)dbenvv; /* * Check if the database exists and if it verifies cleanly. * If it does, run with it; else recreate it and go. Note * that we have to verify outside of the environment. */ #ifdef NOTDEF if ((ret = db_create(&dbp, NULL, 0)) != 0) return (ret); if ((ret = dbp->verify(dbp, DATABASE, NULL, NULL, 0)) != 0) { if ((ret = dbp->remove(dbp, DATABASE, NULL, 0)) != 0 && ret != DB_NOTFOUND && ret != ENOENT) return (ret); #endif if ((ret = db_create(&dbp, dbenv, 0)) != 0) return ((void *)ret); /* Set page size small so we can easily do page allocation. */ if ((ret = dbp->set_pagesize(dbp, 512)) != 0) goto err; if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) goto err; if ((ret = dbp->open(dbp, txn, DATABASE, NULL, DB_BTREE, DB_CREATE /* | DB_THREAD */, 0)) != 0) goto err; ret = txn->commit(txn, 0); txn = NULL; if (ret != 0) { dbp = NULL; goto err; } #ifdef NOTDEF } else { /* Reopen in the environment. */ if ((ret = dbp->close(dbp, 0)) != 0) return (ret); if ((ret = db_create(&dbp, dbenv, 0)) != 0) return (ret); if ((ret = dbp->open(dbp, DATABASE, NULL, DB_UNKNOWN, DB_THREAD, 0)) != 0) goto err; } #endif /* * XXX * It would probably be kind of cool to do this in Tcl and * have a nice GUI. It would also be cool to be independently * wealthy. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); for (;;) { printf("QUOTESERVER> "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) break; (void)strtok(&buf[0], " \t\n"); rbuf = strtok(NULL, " \t\n"); if (rbuf == NULL || rbuf[0] == '\0') { if (strncmp(buf, "exit", 4) == 0 || strncmp(buf, "quit", 4) == 0) break; dbenv->errx(dbenv, "Format: TICKER VALUE"); continue; } key.data = buf; key.size = strlen(buf); data.data = rbuf; data.size = strlen(rbuf); if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) goto err; switch (ret = dbp->put(dbp, txn, &key, &data, 0)) { case 0: break; default: dbp->err(dbp, ret, "DB->put"); if (ret != DB_KEYEXIST) goto err; break; } ret = txn->commit(txn, 0); txn = NULL; if (ret != 0) goto err; } err: if (txn != NULL) (void)txn->abort(txn); if (dbp != NULL) (void)dbp->close(dbp, DB_NOSYNC); return ((void *)ret); }