ex_lock.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  *
  7.  * $Id: ex_lock.c,v 11.6 2001/01/04 14:23:29 dda Exp $
  8.  */
  9. #include "db_config.h"
  10. #ifndef NO_SYSTEM_INCLUDES
  11. #include <sys/types.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <unistd.h>
  15. #endif
  16. #include <db.h>
  17. void db_init __P((char *, u_int32_t, int));
  18. int main __P((int, char *[]));
  19. void usage __P((void));
  20. DB_ENV  *dbenv;
  21. const char
  22. *progname = "ex_lock"; /* Program name. */
  23. int
  24. main(argc, argv)
  25. int argc;
  26. char *argv[];
  27. {
  28. extern char *optarg;
  29. extern int optind;
  30. DBT lock_dbt;
  31. DB_LOCK lock;
  32. DB_LOCK *locks;
  33. db_lockmode_t lock_type;
  34. long held;
  35. u_int32_t len, locker, maxlocks;
  36. int ch, do_unlink, did_get, i, lockid, lockcount, ret;
  37. char *home, opbuf[16], objbuf[1024], lockbuf[16];
  38. home = "TESTDIR";
  39. maxlocks = 0;
  40. do_unlink = 0;
  41. while ((ch = getopt(argc, argv, "h:m:u")) != EOF)
  42. switch (ch) {
  43. case 'h':
  44. home = optarg;
  45. break;
  46. case 'm':
  47. if ((i = atoi(optarg)) <= 0)
  48. usage();
  49. maxlocks = (u_int32_t)i;  /* XXX: possible overflow. */
  50. break;
  51. case 'u':
  52. do_unlink = 1;
  53. break;
  54. case '?':
  55. default:
  56. usage();
  57. }
  58. argc -= optind;
  59. argv += optind;
  60. if (argc != 0)
  61. usage();
  62. /* Initialize the database environment. */
  63. db_init(home, maxlocks, do_unlink);
  64. locks = 0;
  65. lockcount = 0;
  66. /*
  67.  * Accept lock requests.
  68.  */
  69. if ((ret = lock_id(dbenv, &locker)) != 0) {
  70. dbenv->err(dbenv, ret, "unable to get locker id");
  71. (void)dbenv->close(dbenv, 0);
  72. exit (1);
  73. }
  74. lockid = -1;
  75. memset(&lock_dbt, 0, sizeof(lock_dbt));
  76. for (held = 0, did_get = 0;;) {
  77. printf("Operation get/release [get]> ");
  78. fflush(stdout);
  79. if (fgets(opbuf, sizeof(opbuf), stdin) == NULL)
  80. break;
  81. if ((len = strlen(opbuf)) <= 1 || strcmp(opbuf, "getn") == 0) {
  82. /* Acquire a lock. */
  83. printf("input object (text string) to lock> ");
  84. fflush(stdout);
  85. if (fgets(objbuf, sizeof(objbuf), stdin) == NULL)
  86. break;
  87. if ((len = strlen(objbuf)) <= 1)
  88. continue;
  89. do {
  90. printf("lock type read/write [read]> ");
  91. fflush(stdout);
  92. if (fgets(lockbuf,
  93.     sizeof(lockbuf), stdin) == NULL)
  94. break;
  95. len = strlen(lockbuf);
  96. } while (len > 1 &&
  97.     strcmp(lockbuf, "readn") != 0 &&
  98.     strcmp(lockbuf, "writen") != 0);
  99. if (len == 1 || strcmp(lockbuf, "readn") == 0)
  100. lock_type = DB_LOCK_READ;
  101. else
  102. lock_type = DB_LOCK_WRITE;
  103. lock_dbt.data = objbuf;
  104. lock_dbt.size = strlen(objbuf);
  105. ret = lock_get(dbenv, locker,
  106.     DB_LOCK_NOWAIT, &lock_dbt, lock_type, &lock);
  107. if (ret == 0) {
  108. did_get = 1;
  109. lockid = lockcount++;
  110. if (locks == NULL)
  111. locks =
  112.     (DB_LOCK *)malloc(sizeof(DB_LOCK));
  113. else
  114. locks = (DB_LOCK *)realloc(locks,
  115.     lockcount * sizeof(DB_LOCK));
  116. locks[lockid] = lock;
  117. }
  118. } else {
  119. /* Release a lock. */
  120. do {
  121. printf("input lock to release> ");
  122. fflush(stdout);
  123. if (fgets(objbuf,
  124.     sizeof(objbuf), stdin) == NULL)
  125. break;
  126. } while ((len = strlen(objbuf)) <= 1);
  127. lockid = strtol(objbuf, NULL, 16);
  128. if (lockid < 0 || lockid >= lockcount) {
  129. printf("Lock #%d out of rangen", lockid);
  130. continue;
  131. }
  132. lock = locks[lockid];
  133. ret = lock_put(dbenv, &lock);
  134. did_get = 0;
  135. }
  136. switch (ret) {
  137. case 0:
  138. printf("Lock #%d %sn", lockid,
  139.     did_get ? "granted" : "released");
  140. held += did_get ? 1 : -1;
  141. break;
  142. case DB_LOCK_NOTGRANTED:
  143. dbenv->err(dbenv, ret, NULL);
  144. break;
  145. case DB_LOCK_DEADLOCK:
  146. dbenv->err(dbenv, ret,
  147.     "lock_%s", did_get ? "get" : "put");
  148. break;
  149. default:
  150. dbenv->err(dbenv, ret,
  151.     "lock_%s", did_get ? "get" : "put");
  152. (void)dbenv->close(dbenv, 0);
  153. exit (1);
  154. }
  155. }
  156. printf("nClosing lock region %ld locks heldn", held);
  157. if (locks != NULL)
  158. free(locks);
  159. if ((ret = dbenv->close(dbenv, 0)) != 0) {
  160. fprintf(stderr,
  161.     "%s: dbenv->close: %sn", progname, db_strerror(ret));
  162. return (1);
  163. }
  164. return (0);
  165. }
  166. /*
  167.  * db_init --
  168.  * Initialize the environment.
  169.  */
  170. void
  171. db_init(home, maxlocks, do_unlink)
  172. char *home;
  173. u_int32_t maxlocks;
  174. int do_unlink;
  175. {
  176. int ret;
  177. if ((ret = db_env_create(&dbenv, 0)) != 0) {
  178. fprintf(stderr, "%s: db_env_create: %sn",
  179.     progname, db_strerror(ret));
  180. exit (1);
  181. }
  182. if (do_unlink) {
  183. if ((ret = dbenv->remove(dbenv, home, DB_FORCE)) != 0) {
  184. fprintf(stderr, "%s: dbenv->remove: %sn",
  185.     progname, db_strerror(ret));
  186. exit (1);
  187. }
  188. if ((ret = db_env_create(&dbenv, 0)) != 0) {
  189. fprintf(stderr, "%s: db_env_create: %sn",
  190.     progname, db_strerror(ret));
  191. exit (1);
  192. }
  193. }
  194. dbenv->set_errfile(dbenv, stderr);
  195. dbenv->set_errpfx(dbenv, progname);
  196. if (maxlocks != 0)
  197. dbenv->set_lk_max_locks(dbenv, maxlocks);
  198. if ((ret =
  199.     dbenv->open(dbenv, home, DB_CREATE | DB_INIT_LOCK, 0)) != 0) {
  200. dbenv->err(dbenv, ret, NULL);
  201. (void)dbenv->close(dbenv, 0);
  202. exit(1);
  203. }
  204. }
  205. void
  206. usage()
  207. {
  208. (void)fprintf(stderr,
  209.     "usage: %s [-u] [-h home] [-m maxlocks]n", progname);
  210. exit(1);
  211. }