Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

LockExample.cpp

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1997-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: LockExample.cpp,v 12.1 2005/06/16 20:22:14 bostic Exp $
00008  */
00009 
00010 #include <sys/types.h>
00011 
00012 #include <errno.h>
00013 #include <iostream>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 
00017 #include <db_cxx.h>
00018 
00019 using std::cin;
00020 using std::cout;
00021 using std::cerr;
00022 
00023 const char *progname = "LockExample";                           // Program name.
00024 
00025 //
00026 // An example of a program using DBLock and related classes.
00027 //
00028 class LockExample : public DbEnv
00029 {
00030 public:
00031         void run();
00032         int error_code() { return (ecode); }
00033 
00034         LockExample(const char *home, u_int32_t maxlocks, int do_unlink);
00035 
00036 private:
00037         static const char FileName[];
00038         int ecode;
00039 
00040         // no need for copy and assignment
00041         LockExample(const LockExample &);
00042         void operator = (const LockExample &);
00043 };
00044 
00045 static int usage();          // forward
00046 
00047 int
00048 main(int argc, char *argv[])
00049 {
00050         const char *home;
00051         int do_unlink;
00052         u_int32_t maxlocks;
00053         int i;
00054 
00055         home = "TESTDIR";
00056         maxlocks = 0;
00057         do_unlink = 0;
00058         for (int argnum = 1; argnum < argc; ++argnum) {
00059                 if (strcmp(argv[argnum], "-h") == 0) {
00060                         if (++argnum >= argc)
00061                                 return (usage());
00062                         home = argv[argnum];
00063                 }
00064                 else if (strcmp(argv[argnum], "-m") == 0) {
00065                         if (++argnum >= argc)
00066                                 return (usage());
00067                         if ((i = atoi(argv[argnum])) <= 0)
00068                                 return (usage());
00069                         maxlocks = (u_int32_t)i;  /* XXX: possible overflow. */
00070                 }
00071                 else if (strcmp(argv[argnum], "-u") == 0) {
00072                         do_unlink = 1;
00073                 }
00074                 else {
00075                         return (usage());
00076                 }
00077         }
00078 
00079         try {
00080                 int ecode;
00081 
00082                 if (do_unlink) {
00083                         // Create an environment that immediately
00084                         // removes all files.
00085                         LockExample tmp(home, maxlocks, do_unlink);
00086                         if ((ecode = tmp.error_code()) != 0)
00087                                 return (ecode);
00088                 }
00089 
00090                 LockExample app(home, maxlocks, do_unlink);
00091                 if ((ecode = app.error_code()) != 0)
00092                         return (ecode);
00093                 app.run();
00094                 app.close(0);
00095                 return (EXIT_SUCCESS);
00096         }
00097         catch (DbException &dbe) {
00098                 cerr << "LockExample: " << dbe.what() << "\n";
00099                 return (EXIT_FAILURE);
00100         }
00101 }
00102 
00103 LockExample::LockExample(const char *home, u_int32_t maxlocks, int do_unlink)
00104 :       DbEnv(0)
00105 ,       ecode(0)
00106 {
00107         int ret;
00108 
00109         if (do_unlink) {
00110                 if ((ret = remove(home, DB_FORCE)) != 0) {
00111                         cerr << progname << ": DbEnv::remove: "
00112                              << strerror(errno) << "\n";
00113                         ecode = EXIT_FAILURE;
00114                 }
00115         }
00116         else {
00117                 set_error_stream(&cerr);
00118                 set_errpfx("LockExample");
00119                 if (maxlocks != 0)
00120                         set_lk_max_locks(maxlocks);
00121                 open(home, DB_CREATE | DB_INIT_LOCK, 0);
00122         }
00123 }
00124 
00125 void LockExample::run()
00126 {
00127         long held;
00128         size_t len;
00129         u_int32_t locker;
00130         int did_get, ret;
00131         DbLock *locks = 0;
00132         int lockcount = 0;
00133         int lockid = 0;
00134         char objbuf[1024];
00135 
00136         //
00137         // Accept lock requests.
00138         //
00139         lock_id(&locker);
00140         for (held = 0;;) {
00141                 cout << "Operation get/release [get]> ";
00142                 cout.flush();
00143 
00144                 char opbuf[16];
00145                 cin.getline(opbuf, sizeof(opbuf));
00146                 if (cin.eof())
00147                         break;
00148                 if ((len = strlen(opbuf)) <= 1 || strcmp(opbuf, "get") == 0) {
00149                         // Acquire a lock.
00150                         cout << "input object (text string) to lock> ";
00151                         cout.flush();
00152                         cin.getline(objbuf, sizeof(objbuf));
00153                         if (cin.eof())
00154                                 break;
00155                         if ((len = strlen(objbuf)) <= 0)
00156                                 continue;
00157 
00158                         char lockbuf[16];
00159                         do {
00160                                 cout << "lock type read/write [read]> ";
00161                                 cout.flush();
00162                                 cin.getline(lockbuf, sizeof(lockbuf));
00163                                 if (cin.eof())
00164                                         break;
00165                                 len = strlen(lockbuf);
00166                         } while (len >= 1 &&
00167                                  strcmp(lockbuf, "read") != 0 &&
00168                                  strcmp(lockbuf, "write") != 0);
00169 
00170                         db_lockmode_t lock_type;
00171                         if (len <= 1 || strcmp(lockbuf, "read") == 0)
00172                                 lock_type = DB_LOCK_READ;
00173                         else
00174                                 lock_type = DB_LOCK_WRITE;
00175 
00176                         Dbt dbt(objbuf, (u_int32_t)strlen(objbuf));
00177 
00178                         DbLock lock;
00179                         ret = lock_get(locker, DB_LOCK_NOWAIT, &dbt,
00180                                        lock_type, &lock);
00181                         did_get = 1;
00182                         lockid = lockcount++;
00183                         if (locks == NULL) {
00184                                 locks = new DbLock[1];
00185                         }
00186                         else {
00187                                 DbLock *newlocks = new DbLock[lockcount];
00188                                 for (int lockno = 0;
00189                                     lockno < lockid; lockno++) {
00190                                         newlocks[lockno] = locks[lockno];
00191                                 }
00192                                 delete locks;
00193                                 locks = newlocks;
00194                         }
00195                         locks[lockid] = lock;
00196                 } else {
00197                         // Release a lock.
00198                         do {
00199                                 cout << "input lock to release> ";
00200                                 cout.flush();
00201                                 cin.getline(objbuf, sizeof(objbuf));
00202                                 if (cin.eof())
00203                                         break;
00204                         } while ((len = strlen(objbuf)) <= 0);
00205                         lockid = strtol(objbuf, NULL, 16);
00206                         if (lockid < 0 || lockid >= lockcount) {
00207                                 cout << "Lock #" << lockid << " out of range\n";
00208                                 continue;
00209                         }
00210                         DbLock lock = locks[lockid];
00211                         ret = lock_put(&lock);
00212                         did_get = 0;
00213                 }
00214 
00215                 switch (ret) {
00216                 case 0:
00217                         cout << "Lock #" << lockid << " "
00218                              <<  (did_get ? "granted" : "released")
00219                              << "\n";
00220                         held += did_get ? 1 : -1;
00221                         break;
00222                 case DB_LOCK_NOTGRANTED:
00223                         cout << "Lock not granted\n";
00224                         break;
00225                 case DB_LOCK_DEADLOCK:
00226                         cerr << "LockExample: lock_"
00227                              << (did_get ? "get" : "put")
00228                              << ": " << "returned DEADLOCK";
00229                         break;
00230                 default:
00231                         cerr << "LockExample: lock_get: %s",
00232                                 strerror(errno);
00233                 }
00234         }
00235         cout << "\n";
00236         cout << "Closing lock region " << held << " locks held\n";
00237         if (locks != 0)
00238                 delete locks;
00239 }
00240 
00241 static int
00242 usage()
00243 {
00244         cerr << "usage: LockExample [-u] [-h home] [-m maxlocks]\n";
00245         return (EXIT_FAILURE);
00246 }

Generated on Sun Dec 25 12:14:26 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2