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

ex_lock.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1997-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: ex_lock.c,v 12.1 2005/06/16 20:22:05 bostic Exp $
00008  */
00009 
00010 #include <sys/types.h>
00011 
00012 #include <stdlib.h>
00013 #include <string.h>
00014 
00015 #ifdef _WIN32
00016 extern int getopt(int, char * const *, const char *);
00017 #else
00018 #include <unistd.h>
00019 #endif
00020 
00021 #include <db.h>
00022 
00023 int db_init __P((const char *, u_int32_t, int));
00024 int main __P((int, char *[]));
00025 int usage __P((void));
00026 
00027 DB_ENV   *dbenv;
00028 const char
00029         *progname = "ex_lock";                          /* Program name. */
00030 
00031 int
00032 main(argc, argv)
00033         int argc;
00034         char *argv[];
00035 {
00036         extern char *optarg;
00037         extern int optind;
00038         DBT lock_dbt;
00039         DB_LOCK lock;
00040         DB_LOCK *locks;
00041         db_lockmode_t lock_type;
00042         long held;
00043         size_t len;
00044         u_int32_t locker, maxlocks;
00045         int ch, do_unlink, did_get, i, lockid, lockcount, ret;
00046         const char *home;
00047         char opbuf[16], objbuf[1024], lockbuf[16];
00048 
00049         home = "TESTDIR";
00050         maxlocks = 0;
00051         do_unlink = 0;
00052         while ((ch = getopt(argc, argv, "h:m:u")) != EOF)
00053                 switch (ch) {
00054                 case 'h':
00055                         home = optarg;
00056                         break;
00057                 case 'm':
00058                         if ((i = atoi(optarg)) <= 0)
00059                                 return (usage());
00060                         maxlocks = (u_int32_t)i;  /* XXX: possible overflow. */
00061                         break;
00062                 case 'u':
00063                         do_unlink = 1;
00064                         break;
00065                 case '?':
00066                 default:
00067                         return (usage());
00068                 }
00069         argc -= optind;
00070         argv += optind;
00071 
00072         if (argc != 0)
00073                 return (usage());
00074 
00075         /* Initialize the database environment. */
00076         if ((ret = db_init(home, maxlocks, do_unlink)) != 0)
00077                 return (ret);
00078 
00079         locks = 0;
00080         lockcount = 0;
00081 
00082         /*
00083          * Accept lock requests.
00084          */
00085         if ((ret = dbenv->lock_id(dbenv, &locker)) != 0) {
00086                 dbenv->err(dbenv, ret, "unable to get locker id");
00087                 (void)dbenv->close(dbenv, 0);
00088                 return (EXIT_FAILURE);
00089         }
00090         lockid = -1;
00091 
00092         memset(&lock_dbt, 0, sizeof(lock_dbt));
00093         for (held = 0, did_get = 0;;) {
00094                 printf("Operation get/release [get]> ");
00095                 fflush(stdout);
00096                 if (fgets(opbuf, sizeof(opbuf), stdin) == NULL)
00097                         break;
00098                 if ((len = strlen(opbuf)) <= 1 || strcmp(opbuf, "get\n") == 0) {
00099                         /* Acquire a lock. */
00100                         printf("input object (text string) to lock> ");
00101                         fflush(stdout);
00102                         if (fgets(objbuf, sizeof(objbuf), stdin) == NULL)
00103                                 break;
00104                         if ((len = strlen(objbuf)) <= 1)
00105                                 continue;
00106 
00107                         do {
00108                                 printf("lock type read/write [read]> ");
00109                                 fflush(stdout);
00110                                 if (fgets(lockbuf,
00111                                     sizeof(lockbuf), stdin) == NULL)
00112                                         break;
00113                                 len = strlen(lockbuf);
00114                         } while (len > 1 &&
00115                             strcmp(lockbuf, "read\n") != 0 &&
00116                             strcmp(lockbuf, "write\n") != 0);
00117                         if (len == 1 || strcmp(lockbuf, "read\n") == 0)
00118                                 lock_type = DB_LOCK_READ;
00119                         else
00120                                 lock_type = DB_LOCK_WRITE;
00121 
00122                         lock_dbt.data = objbuf;
00123                         lock_dbt.size = (u_int32_t)strlen(objbuf);
00124                         ret = dbenv->lock_get(dbenv, locker,
00125                             DB_LOCK_NOWAIT, &lock_dbt, lock_type, &lock);
00126                         if (ret == 0) {
00127                                 did_get = 1;
00128                                 lockid = lockcount++;
00129                                 if (locks == NULL)
00130                                         locks =
00131                                             (DB_LOCK *)malloc(sizeof(DB_LOCK));
00132                                 else
00133                                         locks = (DB_LOCK *)realloc(locks,
00134                                             lockcount * sizeof(DB_LOCK));
00135                                 locks[lockid] = lock;
00136                         }
00137                 } else {
00138                         /* Release a lock. */
00139                         do {
00140                                 printf("input lock to release> ");
00141                                 fflush(stdout);
00142                                 if (fgets(objbuf,
00143                                     sizeof(objbuf), stdin) == NULL)
00144                                         break;
00145                         } while ((len = strlen(objbuf)) <= 1);
00146                         lockid = strtol(objbuf, NULL, 16);
00147                         if (lockid < 0 || lockid >= lockcount) {
00148                                 printf("Lock #%d out of range\n", lockid);
00149                                 continue;
00150                         }
00151                         lock = locks[lockid];
00152                         ret = dbenv->lock_put(dbenv, &lock);
00153                         did_get = 0;
00154                 }
00155                 switch (ret) {
00156                 case 0:
00157                         printf("Lock #%d %s\n", lockid,
00158                             did_get ? "granted" : "released");
00159                         held += did_get ? 1 : -1;
00160                         break;
00161                 case DB_LOCK_NOTGRANTED:
00162                         dbenv->err(dbenv, ret, NULL);
00163                         break;
00164                 case DB_LOCK_DEADLOCK:
00165                         dbenv->err(dbenv, ret,
00166                             "lock_%s", did_get ? "get" : "put");
00167                         break;
00168                 default:
00169                         dbenv->err(dbenv, ret,
00170                             "lock_%s", did_get ? "get" : "put");
00171                         (void)dbenv->close(dbenv, 0);
00172                         return (EXIT_FAILURE);
00173                 }
00174         }
00175 
00176         printf("\nClosing lock region %ld locks held\n", held);
00177 
00178         if (locks != NULL)
00179                 free(locks);
00180 
00181         if ((ret = dbenv->close(dbenv, 0)) != 0) {
00182                 fprintf(stderr,
00183                     "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00184                 return (EXIT_FAILURE);
00185         }
00186         return (EXIT_SUCCESS);
00187 }
00188 
00189 /*
00190  * db_init --
00191  *      Initialize the environment.
00192  */
00193 int
00194 db_init(home, maxlocks, do_unlink)
00195         const char *home;
00196         u_int32_t maxlocks;
00197         int do_unlink;
00198 {
00199         int ret;
00200 
00201         if ((ret = db_env_create(&dbenv, 0)) != 0) {
00202                 fprintf(stderr, "%s: db_env_create: %s\n",
00203                     progname, db_strerror(ret));
00204                 return (EXIT_FAILURE);
00205         }
00206 
00207         if (do_unlink) {
00208                 if ((ret = dbenv->remove(dbenv, home, DB_FORCE)) != 0) {
00209                         fprintf(stderr, "%s: dbenv->remove: %s\n",
00210                             progname, db_strerror(ret));
00211                         return (EXIT_FAILURE);
00212                 }
00213                 if ((ret = db_env_create(&dbenv, 0)) != 0) {
00214                         fprintf(stderr, "%s: db_env_create: %s\n",
00215                             progname, db_strerror(ret));
00216                         return (EXIT_FAILURE);
00217                 }
00218         }
00219 
00220         dbenv->set_errfile(dbenv, stderr);
00221         dbenv->set_errpfx(dbenv, progname);
00222         if (maxlocks != 0)
00223                 dbenv->set_lk_max_locks(dbenv, maxlocks);
00224 
00225         if ((ret =
00226             dbenv->open(dbenv, home, DB_CREATE | DB_INIT_LOCK, 0)) != 0) {
00227                 dbenv->err(dbenv, ret, NULL);
00228                 (void)dbenv->close(dbenv, 0);
00229                 return (EXIT_FAILURE);
00230         }
00231         return (0);
00232 }
00233 
00234 int
00235 usage()
00236 {
00237         (void)fprintf(stderr,
00238             "usage: %s [-u] [-h home] [-m maxlocks]\n", progname);
00239         return (EXIT_FAILURE);
00240 }

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