LockExample.cpp
上传用户: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: LockExample.cpp,v 11.8 2001/01/04 14:23:30 dda Exp $
  8.  */
  9. #include "db_config.h"
  10. #ifndef NO_SYSTEM_INCLUDES
  11. #include <sys/types.h>
  12. #include <errno.h>
  13. #include <iostream.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #endif
  18. #include <db_cxx.h>
  19. char *progname = "LockExample"; // Program name.
  20. //
  21. // An example of a program using DBLock and related classes.
  22. //
  23. class LockExample : public DbEnv
  24. {
  25. public:
  26. void run();
  27. LockExample(const char *home, u_int32_t maxlocks, int do_unlink);
  28. private:
  29. static const char FileName[];
  30. // no need for copy and assignment
  31. LockExample(const LockExample &);
  32. void operator = (const LockExample &);
  33. };
  34. static void usage();          // forward
  35. int
  36. main(int argc, char *argv[])
  37. {
  38. const char *home;
  39. int do_unlink;
  40. u_int32_t maxlocks;
  41. int i;
  42. home = "TESTDIR";
  43. maxlocks = 0;
  44. do_unlink = 0;
  45. for (int argnum = 1; argnum < argc; ++argnum) {
  46. if (strcmp(argv[argnum], "-h") == 0) {
  47. if (++argnum >= argc)
  48. usage();
  49. home = argv[argnum];
  50. }
  51. else if (strcmp(argv[argnum], "-m") == 0) {
  52. if (++argnum >= argc)
  53. usage();
  54. if ((i = atoi(argv[argnum])) <= 0)
  55. usage();
  56. maxlocks = (u_int32_t)i;  /* XXX: possible overflow. */
  57. }
  58. else if (strcmp(argv[argnum], "-u") == 0) {
  59. do_unlink = 1;
  60. }
  61. else {
  62. usage();
  63. }
  64. }
  65. try {
  66. if (do_unlink) {
  67. // Create an environment that immediately
  68. // removes all files.
  69. LockExample tmp(home, maxlocks, do_unlink);
  70. }
  71. LockExample app(home, maxlocks, do_unlink);
  72. app.run();
  73. app.close(0);
  74. return 0;
  75. }
  76. catch (DbException &dbe) {
  77. cerr << "LockExample: " << dbe.what() << "n";
  78. return 1;
  79. }
  80. }
  81. LockExample::LockExample(const char *home, u_int32_t maxlocks, int do_unlink)
  82. : DbEnv(0)
  83. {
  84. int ret;
  85. if (do_unlink) {
  86. if ((ret = remove(home, DB_FORCE)) != 0) {
  87. cerr << progname << ": DbEnv::remove: "
  88.      << strerror(errno) << "n";
  89. exit (1);
  90. }
  91. }
  92. else {
  93. set_error_stream(&cerr);
  94. set_errpfx("LockExample");
  95. if (maxlocks != 0)
  96. set_lk_max_locks(maxlocks);
  97. open(home, DB_CREATE | DB_INIT_LOCK, 0);
  98. }
  99. }
  100. void LockExample::run()
  101. {
  102. long held;
  103. u_int32_t len, locker;
  104. int did_get, ret;
  105. DbLock *locks = 0;
  106. int lockcount = 0;
  107. char objbuf[1024];
  108. int lockid = 0;
  109. //
  110. // Accept lock requests.
  111. //
  112. lock_id(&locker);
  113. for (held = 0;;) {
  114. cout << "Operation get/release [get]> ";
  115. cout.flush();
  116. char opbuf[16];
  117. cin.getline(opbuf, sizeof(opbuf));
  118. if (cin.eof())
  119. break;
  120. if ((len = strlen(opbuf)) <= 1 || strcmp(opbuf, "get") == 0) {
  121. // Acquire a lock.
  122. cout << "input object (text string) to lock> ";
  123. cout.flush();
  124. cin.getline(objbuf, sizeof(objbuf));
  125. if (cin.eof())
  126. break;
  127. if ((len = strlen(objbuf)) <= 0)
  128. continue;
  129. char lockbuf[16];
  130. do {
  131. cout << "lock type read/write [read]> ";
  132. cout.flush();
  133. cin.getline(lockbuf, sizeof(lockbuf));
  134. if (cin.eof())
  135. break;
  136. len = strlen(lockbuf);
  137. } while (len >= 1 &&
  138.  strcmp(lockbuf, "read") != 0 &&
  139.  strcmp(lockbuf, "write") != 0);
  140. db_lockmode_t lock_type;
  141. if (len <= 1 || strcmp(lockbuf, "read") == 0)
  142. lock_type = DB_LOCK_READ;
  143. else
  144. lock_type = DB_LOCK_WRITE;
  145. Dbt dbt(objbuf, strlen(objbuf));
  146. DbLock lock;
  147. ret = lock_get(locker, DB_LOCK_NOWAIT, &dbt,
  148.        lock_type, &lock);
  149. did_get = 1;
  150. lockid = lockcount++;
  151. if (locks == NULL) {
  152. locks = new DbLock[1];
  153. }
  154. else {
  155. DbLock *newlocks = new DbLock[lockcount];
  156. for (int lockno = 0; lockno < lockid; lockno++) {
  157. newlocks[lockno] = locks[lockno];
  158. }
  159. delete locks;
  160. locks = newlocks;
  161. }
  162. locks[lockid] = lock;
  163. } else {
  164. // Release a lock.
  165. do {
  166. cout << "input lock to release> ";
  167. cout.flush();
  168. cin.getline(objbuf, sizeof(objbuf));
  169. if (cin.eof())
  170. break;
  171. } while ((len = strlen(objbuf)) <= 0);
  172. lockid = strtol(objbuf, NULL, 16);
  173. if (lockid < 0 || lockid >= lockcount) {
  174. cout << "Lock #" << lockid << " out of rangen";
  175. continue;
  176. }
  177. DbLock lock = locks[lockid];
  178. ret = lock.put(this);
  179. did_get = 0;
  180. }
  181. switch (ret) {
  182. case 0:
  183. cout << "Lock #" << lockid << " "
  184.      <<  (did_get ? "granted" : "released")
  185.      << "n";
  186. held += did_get ? 1 : -1;
  187. break;
  188. case DB_LOCK_NOTGRANTED:
  189. cout << "Lock not grantedn";
  190. break;
  191. case DB_LOCK_DEADLOCK:
  192. cerr << "LockExample: lock_"
  193.      << (did_get ? "get" : "put")
  194.      << ": " << "returned DEADLOCK";
  195. break;
  196. default:
  197. cerr << "LockExample: lock_get: %s",
  198. strerror(errno);
  199. }
  200. }
  201. cout << "n";
  202. cout << "Closing lock region " << held << " locks heldn";
  203. if (locks != 0)
  204. delete locks;
  205. }
  206. static void
  207. usage()
  208. {
  209. cerr << "usage: LockExample [-u] [-h home] [-m maxlocks]n";
  210. exit(1);
  211. }