summaryrefslogtreecommitdiff
path: root/db/examples_cxx/LockExample.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'db/examples_cxx/LockExample.cpp')
-rw-r--r--db/examples_cxx/LockExample.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/db/examples_cxx/LockExample.cpp b/db/examples_cxx/LockExample.cpp
new file mode 100644
index 000000000..cfab28680
--- /dev/null
+++ b/db/examples_cxx/LockExample.cpp
@@ -0,0 +1,236 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000
+ * Sleepycat Software. All rights reserved.
+ *
+ * $Id: LockExample.cpp,v 11.8 2001/01/04 14:23:30 dda Exp $
+ */
+
+#include "db_config.h"
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <iostream.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+#include <db_cxx.h>
+
+char *progname = "LockExample"; // Program name.
+
+//
+// An example of a program using DBLock and related classes.
+//
+class LockExample : public DbEnv
+{
+public:
+ void run();
+
+ LockExample(const char *home, u_int32_t maxlocks, int do_unlink);
+
+private:
+ static const char FileName[];
+
+ // no need for copy and assignment
+ LockExample(const LockExample &);
+ void operator = (const LockExample &);
+};
+
+static void usage(); // forward
+
+int
+main(int argc, char *argv[])
+{
+ const char *home;
+ int do_unlink;
+ u_int32_t maxlocks;
+ int i;
+
+ home = "TESTDIR";
+ maxlocks = 0;
+ do_unlink = 0;
+ for (int argnum = 1; argnum < argc; ++argnum) {
+ if (strcmp(argv[argnum], "-h") == 0) {
+ if (++argnum >= argc)
+ usage();
+ home = argv[argnum];
+ }
+ else if (strcmp(argv[argnum], "-m") == 0) {
+ if (++argnum >= argc)
+ usage();
+ if ((i = atoi(argv[argnum])) <= 0)
+ usage();
+ maxlocks = (u_int32_t)i; /* XXX: possible overflow. */
+ }
+ else if (strcmp(argv[argnum], "-u") == 0) {
+ do_unlink = 1;
+ }
+ else {
+ usage();
+ }
+ }
+
+ try {
+ if (do_unlink) {
+ // Create an environment that immediately
+ // removes all files.
+ LockExample tmp(home, maxlocks, do_unlink);
+ }
+
+ LockExample app(home, maxlocks, do_unlink);
+ app.run();
+ app.close(0);
+ return 0;
+ }
+ catch (DbException &dbe) {
+ cerr << "LockExample: " << dbe.what() << "\n";
+ return 1;
+ }
+}
+
+LockExample::LockExample(const char *home, u_int32_t maxlocks, int do_unlink)
+: DbEnv(0)
+{
+ int ret;
+
+ if (do_unlink) {
+ if ((ret = remove(home, DB_FORCE)) != 0) {
+ cerr << progname << ": DbEnv::remove: "
+ << strerror(errno) << "\n";
+ exit (1);
+ }
+ }
+ else {
+ set_error_stream(&cerr);
+ set_errpfx("LockExample");
+ if (maxlocks != 0)
+ set_lk_max_locks(maxlocks);
+ open(home, DB_CREATE | DB_INIT_LOCK, 0);
+ }
+}
+
+void LockExample::run()
+{
+ long held;
+ u_int32_t len, locker;
+ int did_get, ret;
+ DbLock *locks = 0;
+ int lockcount = 0;
+ char objbuf[1024];
+ int lockid = 0;
+
+ //
+ // Accept lock requests.
+ //
+ lock_id(&locker);
+ for (held = 0;;) {
+ cout << "Operation get/release [get]> ";
+ cout.flush();
+
+ char opbuf[16];
+ cin.getline(opbuf, sizeof(opbuf));
+ if (cin.eof())
+ break;
+ if ((len = strlen(opbuf)) <= 1 || strcmp(opbuf, "get") == 0) {
+ // Acquire a lock.
+ cout << "input object (text string) to lock> ";
+ cout.flush();
+ cin.getline(objbuf, sizeof(objbuf));
+ if (cin.eof())
+ break;
+ if ((len = strlen(objbuf)) <= 0)
+ continue;
+
+ char lockbuf[16];
+ do {
+ cout << "lock type read/write [read]> ";
+ cout.flush();
+ cin.getline(lockbuf, sizeof(lockbuf));
+ if (cin.eof())
+ break;
+ len = strlen(lockbuf);
+ } while (len >= 1 &&
+ strcmp(lockbuf, "read") != 0 &&
+ strcmp(lockbuf, "write") != 0);
+
+ db_lockmode_t lock_type;
+ if (len <= 1 || strcmp(lockbuf, "read") == 0)
+ lock_type = DB_LOCK_READ;
+ else
+ lock_type = DB_LOCK_WRITE;
+
+ Dbt dbt(objbuf, strlen(objbuf));
+
+ DbLock lock;
+ ret = lock_get(locker, DB_LOCK_NOWAIT, &dbt,
+ lock_type, &lock);
+ did_get = 1;
+ lockid = lockcount++;
+ if (locks == NULL) {
+ locks = new DbLock[1];
+ }
+ else {
+ DbLock *newlocks = new DbLock[lockcount];
+ for (int lockno = 0; lockno < lockid; lockno++) {
+ newlocks[lockno] = locks[lockno];
+ }
+ delete locks;
+ locks = newlocks;
+ }
+ locks[lockid] = lock;
+ } else {
+ // Release a lock.
+ do {
+ cout << "input lock to release> ";
+ cout.flush();
+ cin.getline(objbuf, sizeof(objbuf));
+ if (cin.eof())
+ break;
+ } while ((len = strlen(objbuf)) <= 0);
+ lockid = strtol(objbuf, NULL, 16);
+ if (lockid < 0 || lockid >= lockcount) {
+ cout << "Lock #" << lockid << " out of range\n";
+ continue;
+ }
+ DbLock lock = locks[lockid];
+ ret = lock.put(this);
+ did_get = 0;
+ }
+
+ switch (ret) {
+ case 0:
+ cout << "Lock #" << lockid << " "
+ << (did_get ? "granted" : "released")
+ << "\n";
+ held += did_get ? 1 : -1;
+ break;
+ case DB_LOCK_NOTGRANTED:
+ cout << "Lock not granted\n";
+ break;
+ case DB_LOCK_DEADLOCK:
+ cerr << "LockExample: lock_"
+ << (did_get ? "get" : "put")
+ << ": " << "returned DEADLOCK";
+ break;
+ default:
+ cerr << "LockExample: lock_get: %s",
+ strerror(errno);
+ }
+ }
+ cout << "\n";
+ cout << "Closing lock region " << held << " locks held\n";
+ if (locks != 0)
+ delete locks;
+}
+
+static void
+usage()
+{
+ cerr << "usage: LockExample [-u] [-h home] [-m maxlocks]\n";
+ exit(1);
+}