IOWA 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (502) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTORS +14 -0
  3. data/README.md +23 -0
  4. data/RELEASE_NOTES +77 -0
  5. data/ToDo +21 -0
  6. data/components/CRUDList/CRUDList.html +13 -0
  7. data/components/CRUDList/CRUDList.iwa +136 -0
  8. data/components/Content/Content.html +0 -0
  9. data/components/Content/Content.iwa +143 -0
  10. data/components/Content/example/README +9 -0
  11. data/components/Content/example/cgi/iowa.cgi +10 -0
  12. data/components/Content/example/demo.rb +30 -0
  13. data/components/Content/example/doc/index.html +7 -0
  14. data/components/Content/example/iowa/Content.html +1 -0
  15. data/components/Content/example/iowa/Content.iwa +1 -0
  16. data/components/Content/example/iowa/Main.html +6 -0
  17. data/components/Content/example/iowa/Main.iwa +3 -0
  18. data/components/Content/example/iowa/_content/body +7 -0
  19. data/components/Content/example/iowa/_content/body2 +3 -0
  20. data/components/Content/example/iowa/_content/title +2 -0
  21. data/components/Content/example/iowa/app.cnf +8 -0
  22. data/components/Content/example/iowa/app.rb +8 -0
  23. data/components/Content/example/webrick.rb +38 -0
  24. data/components/Include/Include.html +1 -0
  25. data/components/Include/Include.iwa +30 -0
  26. data/components/Include/readme +5 -0
  27. data/components/JumpTo/JumpTo.html +8 -0
  28. data/components/JumpTo/JumpTo.iwa +8 -0
  29. data/components/JumpTo/readme +6 -0
  30. data/doc/Architecture.txt +6 -0
  31. data/doc/History.txt +33 -0
  32. data/doc/StandardDispatcher.txt +19 -0
  33. data/examples/blog/README +1 -0
  34. data/examples/hello_world/README +17 -0
  35. data/examples/hello_world/htdocs/hello_world_html.html +24 -0
  36. data/examples/hello_world/htdocs/hello_world_ruby.html +41 -0
  37. data/examples/hello_world/iowa/HelloWorld.html +14 -0
  38. data/examples/hello_world/iowa/HelloWorld.iwa +31 -0
  39. data/examples/hello_world/iowa/Index.html +16 -0
  40. data/examples/hello_world/iowa/Index.iwa +5 -0
  41. data/examples/hello_world/iowa/iowa_hello_world.cnf +19 -0
  42. data/examples/hello_world/iowa/iowa_hello_world.rb +5 -0
  43. data/examples/hello_world/iowa/mapfile.cnf +6 -0
  44. data/examples/hw1/iowa/Main.html +1 -0
  45. data/examples/hw1/iowa/README +9 -0
  46. data/examples/hw1/iowa/hw.rb +4 -0
  47. data/examples/hw2/iowa/Main.html +10 -0
  48. data/examples/hw2/iowa/Main.iwa +7 -0
  49. data/examples/hw2/iowa/README +16 -0
  50. data/examples/hw2/iowa/hw.rb +4 -0
  51. data/examples/hw3/iowa/Main.html +11 -0
  52. data/examples/hw3/iowa/Main.iwa +7 -0
  53. data/examples/hw3/iowa/README +22 -0
  54. data/examples/hw3/iowa/hw.rb +4 -0
  55. data/examples/hw4/iowa/Greetings.html +10 -0
  56. data/examples/hw4/iowa/Greetings.iwa +9 -0
  57. data/examples/hw4/iowa/Main.html +12 -0
  58. data/examples/hw4/iowa/Main.iwa +10 -0
  59. data/examples/hw4/iowa/README +28 -0
  60. data/examples/hw4/iowa/hw.rb +4 -0
  61. data/examples/hw5/iowa/Footer.html +2 -0
  62. data/examples/hw5/iowa/Greetings.html +4 -0
  63. data/examples/hw5/iowa/Greetings.iwa +12 -0
  64. data/examples/hw5/iowa/Header.html +6 -0
  65. data/examples/hw5/iowa/Main.html +12 -0
  66. data/examples/hw5/iowa/Main.iwa +13 -0
  67. data/examples/hw5/iowa/README +16 -0
  68. data/examples/hw5/iowa/hw.rb +4 -0
  69. data/examples/template_server/iowa/Content.iwa +121 -0
  70. data/examples/template_server/iowa/Content.view +0 -0
  71. data/examples/template_server/iowa/DBContentDispatcher.rb +112 -0
  72. data/examples/template_server/iowa/DBContentPage.html +3 -0
  73. data/examples/template_server/iowa/DBContentPage.iwa +85 -0
  74. data/examples/template_server/iowa/app.cnf +13 -0
  75. data/examples/template_server/iowa/app.rb +5 -0
  76. data/ext/Classifier/classifier.c +256 -0
  77. data/ext/Classifier/ext_help.h +14 -0
  78. data/ext/Classifier/extconf.rb +5 -0
  79. data/ext/Classifier/tst.h +40 -0
  80. data/ext/Classifier/tst_cleanup.c +24 -0
  81. data/ext/Classifier/tst_delete.c +146 -0
  82. data/ext/Classifier/tst_grow_node_free_list.c +38 -0
  83. data/ext/Classifier/tst_init.c +41 -0
  84. data/ext/Classifier/tst_insert.c +192 -0
  85. data/ext/Classifier/tst_search.c +68 -0
  86. data/ext/http11/README +11 -0
  87. data/ext/http11/ext_help.h +15 -0
  88. data/ext/http11/extconf.rb +5 -0
  89. data/ext/http11/http11.c +534 -0
  90. data/ext/http11/http11.c.dif +422 -0
  91. data/ext/http11/http11_parser.c +1243 -0
  92. data/ext/http11/http11_parser.c.dif +193 -0
  93. data/ext/http11/http11_parser.h +49 -0
  94. data/ext/http11/http11_parser.h.dif +20 -0
  95. data/ext/http11/http11_parser.rl +192 -0
  96. data/ext/httpmachine/Makefile +149 -0
  97. data/ext/httpmachine/extconf.rb +33 -0
  98. data/ext/httpmachine/http.cpp +430 -0
  99. data/ext/httpmachine/http.h +156 -0
  100. data/ext/httpmachine/rubyhttp.cpp +165 -0
  101. data/external/mime-types/LICENCE +18 -0
  102. data/external/mime-types/README +46 -0
  103. data/external/mime-types/doc/classes/MIME.html +120 -0
  104. data/external/mime-types/doc/classes/MIME/InvalidContentType.html +119 -0
  105. data/external/mime-types/doc/classes/MIME/Type.html +866 -0
  106. data/external/mime-types/doc/classes/MIME/Type.src/M000010.html +22 -0
  107. data/external/mime-types/doc/classes/MIME/Type.src/M000011.html +18 -0
  108. data/external/mime-types/doc/classes/MIME/Type.src/M000012.html +19 -0
  109. data/external/mime-types/doc/classes/MIME/Type.src/M000013.html +18 -0
  110. data/external/mime-types/doc/classes/MIME/Type.src/M000014.html +26 -0
  111. data/external/mime-types/doc/classes/MIME/Type.src/M000015.html +33 -0
  112. data/external/mime-types/doc/classes/MIME/Type.src/M000016.html +27 -0
  113. data/external/mime-types/doc/classes/MIME/Type.src/M000017.html +35 -0
  114. data/external/mime-types/doc/classes/MIME/Type.src/M000018.html +34 -0
  115. data/external/mime-types/doc/classes/MIME/Type.src/M000019.html +24 -0
  116. data/external/mime-types/doc/classes/MIME/Type.src/M000020.html +38 -0
  117. data/external/mime-types/doc/classes/MIME/Type.src/M000021.html +22 -0
  118. data/external/mime-types/doc/classes/MIME/Type.src/M000022.html +18 -0
  119. data/external/mime-types/doc/classes/MIME/Type.src/M000023.html +18 -0
  120. data/external/mime-types/doc/classes/MIME/Type.src/M000024.html +18 -0
  121. data/external/mime-types/doc/classes/MIME/Type.src/M000025.html +18 -0
  122. data/external/mime-types/doc/classes/MIME/Type.src/M000026.html +18 -0
  123. data/external/mime-types/doc/classes/MIME/Type.src/M000027.html +18 -0
  124. data/external/mime-types/doc/classes/MIME/Type.src/M000028.html +18 -0
  125. data/external/mime-types/doc/classes/MIME/Type.src/M000029.html +18 -0
  126. data/external/mime-types/doc/classes/MIME/Type.src/M000030.html +19 -0
  127. data/external/mime-types/doc/classes/MIME/Type.src/M000031.html +26 -0
  128. data/external/mime-types/doc/classes/MIME/Types.html +459 -0
  129. data/external/mime-types/doc/classes/MIME/Types.src/M000001.html +19 -0
  130. data/external/mime-types/doc/classes/MIME/Types.src/M000002.html +32 -0
  131. data/external/mime-types/doc/classes/MIME/Types.src/M000003.html +21 -0
  132. data/external/mime-types/doc/classes/MIME/Types.src/M000004.html +18 -0
  133. data/external/mime-types/doc/classes/MIME/Types.src/M000005.html +26 -0
  134. data/external/mime-types/doc/classes/MIME/Types.src/M000006.html +18 -0
  135. data/external/mime-types/doc/classes/MIME/Types.src/M000007.html +18 -0
  136. data/external/mime-types/doc/classes/MIME/Types.src/M000008.html +18 -0
  137. data/external/mime-types/doc/classes/MIME/Types.src/M000009.html +18 -0
  138. data/external/mime-types/doc/created.rid +1 -0
  139. data/external/mime-types/doc/files/ChangeLog.html +320 -0
  140. data/external/mime-types/doc/files/README.html +145 -0
  141. data/external/mime-types/doc/files/lib/mime/types_rb.html +101 -0
  142. data/external/mime-types/doc/fr_class_index.html +30 -0
  143. data/external/mime-types/doc/fr_file_index.html +29 -0
  144. data/external/mime-types/doc/fr_method_index.html +57 -0
  145. data/external/mime-types/doc/index.html +24 -0
  146. data/external/mime-types/doc/rdoc-style.css +208 -0
  147. data/external/mime-types/lib/mime/types.rb +1558 -0
  148. data/external/package.rb +672 -0
  149. data/external/test_support.rb +95 -0
  150. data/external/tmail/README +7 -0
  151. data/external/tmail/tmail.rb +4 -0
  152. data/external/tmail/tmail/address.rb +222 -0
  153. data/external/tmail/tmail/base64.rb +52 -0
  154. data/external/tmail/tmail/compat.rb +39 -0
  155. data/external/tmail/tmail/config.rb +50 -0
  156. data/external/tmail/tmail/encode.rb +447 -0
  157. data/external/tmail/tmail/header.rb +895 -0
  158. data/external/tmail/tmail/info.rb +14 -0
  159. data/external/tmail/tmail/loader.rb +1 -0
  160. data/external/tmail/tmail/mail.rb +869 -0
  161. data/external/tmail/tmail/mailbox.rb +386 -0
  162. data/external/tmail/tmail/mbox.rb +1 -0
  163. data/external/tmail/tmail/net.rb +260 -0
  164. data/external/tmail/tmail/obsolete.rb +123 -0
  165. data/external/tmail/tmail/parser.rb +1475 -0
  166. data/external/tmail/tmail/parser.y +372 -0
  167. data/external/tmail/tmail/port.rb +356 -0
  168. data/external/tmail/tmail/scanner.rb +17 -0
  169. data/external/tmail/tmail/scanner_r.rb +243 -0
  170. data/external/tmail/tmail/stringio.rb +256 -0
  171. data/external/tmail/tmail/textutils.rb +197 -0
  172. data/external/tmail/tmail/tmail.rb +1 -0
  173. data/external/tmail/tmail/utils.rb +23 -0
  174. data/external/win32-process/README +133 -0
  175. data/external/win32-process/lib/win32/process.rb +561 -0
  176. data/external/windows-pr/README +145 -0
  177. data/external/windows-pr/doc/conversion_guide.txt +25 -0
  178. data/external/windows-pr/lib/windows/clipboard.rb +72 -0
  179. data/external/windows-pr/lib/windows/console.rb +323 -0
  180. data/external/windows-pr/lib/windows/device_io.rb +88 -0
  181. data/external/windows-pr/lib/windows/directory.rb +80 -0
  182. data/external/windows-pr/lib/windows/error.rb +313 -0
  183. data/external/windows-pr/lib/windows/eventlog.rb +120 -0
  184. data/external/windows-pr/lib/windows/file.rb +349 -0
  185. data/external/windows-pr/lib/windows/filesystem.rb +16 -0
  186. data/external/windows-pr/lib/windows/handle.rb +31 -0
  187. data/external/windows-pr/lib/windows/library.rb +76 -0
  188. data/external/windows-pr/lib/windows/limits.rb +13 -0
  189. data/external/windows-pr/lib/windows/memory.rb +117 -0
  190. data/external/windows-pr/lib/windows/msvcrt/buffer.rb +48 -0
  191. data/external/windows-pr/lib/windows/msvcrt/file.rb +18 -0
  192. data/external/windows-pr/lib/windows/msvcrt/string.rb +46 -0
  193. data/external/windows-pr/lib/windows/national.rb +557 -0
  194. data/external/windows-pr/lib/windows/path.rb +296 -0
  195. data/external/windows-pr/lib/windows/pipe.rb +77 -0
  196. data/external/windows-pr/lib/windows/process.rb +171 -0
  197. data/external/windows-pr/lib/windows/registry.rb +238 -0
  198. data/external/windows-pr/lib/windows/security.rb +89 -0
  199. data/external/windows-pr/lib/windows/service.rb +183 -0
  200. data/external/windows-pr/lib/windows/shell.rb +88 -0
  201. data/external/windows-pr/lib/windows/sound.rb +52 -0
  202. data/external/windows-pr/lib/windows/synchronize.rb +161 -0
  203. data/external/windows-pr/lib/windows/system_info.rb +70 -0
  204. data/external/windows-pr/lib/windows/unicode.rb +138 -0
  205. data/external/windows-pr/lib/windows/window.rb +22 -0
  206. data/iowa.gemspec +45 -0
  207. data/microprojects/DiskCache/LICENSE +28 -0
  208. data/microprojects/DiskCache/README +17 -0
  209. data/microprojects/DiskCache/external/package.rb +608 -0
  210. data/microprojects/DiskCache/external/test_support.rb +8 -0
  211. data/microprojects/DiskCache/setup.rb +22 -0
  212. data/microprojects/DiskCache/src/iowa/Association.rb +67 -0
  213. data/microprojects/DiskCache/src/iowa/Constants.rb +159 -0
  214. data/microprojects/DiskCache/src/iowa/DiskStore.rb +377 -0
  215. data/microprojects/DiskCache/src/iowa/Hash.rb +63 -0
  216. data/microprojects/DiskCache/src/iowa/Lockfile.rb +575 -0
  217. data/microprojects/DiskCache/src/iowa/Mutex.rb +142 -0
  218. data/microprojects/DiskCache/src/iowa/caches/DiskCache.rb +605 -0
  219. data/microprojects/DiskCache/src/iowa/caches/LRUCache.rb +287 -0
  220. data/microprojects/DiskCache/test/TC_DiskCache.rb +218 -0
  221. data/microprojects/LRUCache/LICENSE +28 -0
  222. data/microprojects/LRUCache/README +13 -0
  223. data/microprojects/LRUCache/external/package.rb +608 -0
  224. data/microprojects/LRUCache/external/test_support.rb +8 -0
  225. data/microprojects/LRUCache/setup.rb +22 -0
  226. data/microprojects/LRUCache/src/iowa/Association.rb +57 -0
  227. data/microprojects/LRUCache/src/iowa/Constants.rb +159 -0
  228. data/microprojects/LRUCache/src/iowa/Hash.rb +63 -0
  229. data/microprojects/LRUCache/src/iowa/Mutex.rb +129 -0
  230. data/microprojects/LRUCache/src/iowa/caches/LRUCache.rb +287 -0
  231. data/microprojects/LRUCache/test/TC_LRUCache.rb +65 -0
  232. data/microprojects/LinkedList/LICENSE +28 -0
  233. data/microprojects/LinkedList/README +13 -0
  234. data/microprojects/LinkedList/external/package.rb +608 -0
  235. data/microprojects/LinkedList/external/test_support.rb +8 -0
  236. data/microprojects/LinkedList/setup.rb +22 -0
  237. data/microprojects/LinkedList/src/iowa/LinkedList.rb +165 -0
  238. data/microprojects/LinkedList/test/TC_LinkedList.rb +42 -0
  239. data/microprojects/README +8 -0
  240. data/setup.rb +116 -0
  241. data/share/iowa/app_skeleton/Main.html +8 -0
  242. data/share/iowa/app_skeleton/Main.iwa +15 -0
  243. data/share/iowa/app_skeleton/app.cnf +48 -0
  244. data/share/iowa/app_skeleton/app.rb +58 -0
  245. data/share/iowa/app_skeleton/models/model.rb +49 -0
  246. data/src/ihc.rb +223 -0
  247. data/src/iowa.cgi +29 -0
  248. data/src/iowa.rb +637 -0
  249. data/src/iowa/AbstractCache.rb +96 -0
  250. data/src/iowa/AcceptLanguage.rb +76 -0
  251. data/src/iowa/Application.rb +928 -0
  252. data/src/iowa/ApplicationStats.rb +72 -0
  253. data/src/iowa/Association.rb +67 -0
  254. data/src/iowa/BindingsParser.rb +62 -0
  255. data/src/iowa/Breakpoint.rb +273 -0
  256. data/src/iowa/CSS.rb +564 -0
  257. data/src/iowa/Client.rb +192 -0
  258. data/src/iowa/Component.rb +405 -0
  259. data/src/iowa/ComponentProxy.rb +26 -0
  260. data/src/iowa/Config.rb +21 -0
  261. data/src/iowa/Constants.rb +226 -0
  262. data/src/iowa/Context.rb +218 -0
  263. data/src/iowa/ContextLogger.rb +16 -0
  264. data/src/iowa/DbPool.rb +222 -0
  265. data/src/iowa/DetachedComponent.rb +18 -0
  266. data/src/iowa/Dispatcher.rb +27 -0
  267. data/src/iowa/DynamicElements.rb +471 -0
  268. data/src/iowa/Element.rb +100 -0
  269. data/src/iowa/Email.rb +287 -0
  270. data/src/iowa/Extensions/AllExtensions.rb +4 -0
  271. data/src/iowa/Extensions/Class.rb +94 -0
  272. data/src/iowa/Extensions/Date.rb +88 -0
  273. data/src/iowa/Extensions/DateTime.rb +88 -0
  274. data/src/iowa/Extensions/Hash.rb +22 -0
  275. data/src/iowa/Extensions/Kernel.rb +6 -0
  276. data/src/iowa/Extensions/Numeric.rb +47 -0
  277. data/src/iowa/Extensions/Object.rb +11 -0
  278. data/src/iowa/Extensions/String.rb +60 -0
  279. data/src/iowa/Extensions/Time.rb +89 -0
  280. data/src/iowa/Extensions/TimeExtensions.rb +6 -0
  281. data/src/iowa/Form.rb +368 -0
  282. data/src/iowa/Hash.rb +85 -0
  283. data/src/iowa/ISAAC.rb +175 -0
  284. data/src/iowa/ImageSize.rb +279 -0
  285. data/src/iowa/IowaComponentMixins.rb +7 -0
  286. data/src/iowa/JSON-lexer.rb +296 -0
  287. data/src/iowa/JSON-objects.rb +201 -0
  288. data/src/iowa/KeyValueCoding.rb +91 -0
  289. data/src/iowa/LinkedList.rb +175 -0
  290. data/src/iowa/Loader.rb +22 -0
  291. data/src/iowa/Lockfile.rb +575 -0
  292. data/src/iowa/Logger.rb +74 -0
  293. data/src/iowa/Monkey.rb +20 -0
  294. data/src/iowa/Mutex.rb +142 -0
  295. data/src/iowa/Policy.rb +70 -0
  296. data/src/iowa/Pool.rb +243 -0
  297. data/src/iowa/PrettyException.rb +1091 -0
  298. data/src/iowa/Request.rb +244 -0
  299. data/src/iowa/Response.rb +133 -0
  300. data/src/iowa/Session.rb +354 -0
  301. data/src/iowa/SessionStats.rb +78 -0
  302. data/src/iowa/String.rb +65 -0
  303. data/src/iowa/Tag.rb +101 -0
  304. data/src/iowa/TemplateParser.rb +236 -0
  305. data/src/iowa/Util.rb +314 -0
  306. data/src/iowa/Webcache.rb +122 -0
  307. data/src/iowa/caches/BiLevelCache.rb +65 -0
  308. data/src/iowa/caches/ClassLimitedCache.rb +67 -0
  309. data/src/iowa/caches/DiskCache.rb +609 -0
  310. data/src/iowa/caches/DiskStore.rb +380 -0
  311. data/src/iowa/caches/LRUCache-alternative.rb +155 -0
  312. data/src/iowa/caches/LRUCache.rb +290 -0
  313. data/src/iowa/caches/SimpleLRUCache.rb +112 -0
  314. data/src/iowa/dispatchers/StandardDispatcher.rb +396 -0
  315. data/src/iowa/dispatchers/StandardDispatcherWithClassifier.rb +93 -0
  316. data/src/iowa/js/iowa_jsonrpc.js +381 -0
  317. data/src/iowa/js/jsonrpc.js +187 -0
  318. data/src/iowa/js/jsonrpc_async.js +261 -0
  319. data/src/iowa/loaders/DiskLoader.rb +50 -0
  320. data/src/iowa/loggers/Analogger.rb +54 -0
  321. data/src/iowa/loggers/AsyncLogger.rb +54 -0
  322. data/src/iowa/loggers/BitBucket.rb +38 -0
  323. data/src/iowa/loggers/Log4R.rb +13 -0
  324. data/src/iowa/loggers/Log4rLogger.rb +48 -0
  325. data/src/iowa/loggers/Logger.rb +29 -0
  326. data/src/iowa/loggers/RubyLogger.rb +9 -0
  327. data/src/iowa/pools/DBConnectionPool.rb +53 -0
  328. data/src/iowa/request/Apache.rb +90 -0
  329. data/src/iowa/request/EMHybrid.rb +59 -0
  330. data/src/iowa/request/ENV.rb +80 -0
  331. data/src/iowa/request/FCGI.rb +68 -0
  332. data/src/iowa/request/HTTPMachine.rb +75 -0
  333. data/src/iowa/request/Mongrel.rb +68 -0
  334. data/src/iowa/request/WEBrick.rb +48 -0
  335. data/src/iowa/version.rb +3 -0
  336. data/src/iowa/webrick/HTTPServer.rb +43 -0
  337. data/src/iowa/webrick/WEBrickServlet.rb +28 -0
  338. data/src/iowa_fcgi_handler.rb +101 -0
  339. data/src/iowa_httpmachine.rb +141 -0
  340. data/src/iowa_hybrid.rb +193 -0
  341. data/src/iowa_hybrid_cluster.rb +231 -0
  342. data/src/iowa_mongrel.rb +136 -0
  343. data/src/iowa_webrick.rb +194 -0
  344. data/src/iowa_webrick_legacy.rb +104 -0
  345. data/src/mod_iowa.rb +104 -0
  346. data/tcss.rb +61 -0
  347. data/test/README.windows +12 -0
  348. data/test/TC_AcceptLanguage.rb +61 -0
  349. data/test/TC_AppConfig.rb +43 -0
  350. data/test/TC_AppConfig/cgi/iowa.cgi +7 -0
  351. data/test/TC_AppConfig/doc/index.html +1 -0
  352. data/test/TC_AppConfig/iowa/Main.html +4 -0
  353. data/test/TC_AppConfig/iowa/Main.iwa +17 -0
  354. data/test/TC_AppConfig/iowa/README +1 -0
  355. data/test/TC_AppConfig/iowa/app.cnf +19 -0
  356. data/test/TC_AppConfig/iowa/app.rb +8 -0
  357. data/test/TC_AppConfig/webrick.rb +38 -0
  358. data/test/TC_Association.rb +29 -0
  359. data/test/TC_BiLevelCache.rb +71 -0
  360. data/test/TC_CGI_Adaptor.rb +55 -0
  361. data/test/TC_CGI_Adaptor/cgi/iowa.cgi +7 -0
  362. data/test/TC_CGI_Adaptor/doc/index.html +1 -0
  363. data/test/TC_CGI_Adaptor/iowa/Main.html +8 -0
  364. data/test/TC_CGI_Adaptor/iowa/Main.iwa +14 -0
  365. data/test/TC_CGI_Adaptor/iowa/README +1 -0
  366. data/test/TC_CGI_Adaptor/iowa/app.cnf +8 -0
  367. data/test/TC_CGI_Adaptor/iowa/app.rb +8 -0
  368. data/test/TC_CGI_Adaptor/webrick.rb +38 -0
  369. data/test/TC_CSS.rb +660 -0
  370. data/test/TC_ClassLimitedCache.rb +89 -0
  371. data/test/TC_Classifier.rb +80 -0
  372. data/test/TC_DbPool.rb +127 -0
  373. data/test/TC_DiskCache.rb +218 -0
  374. data/test/TC_Hybrid.rb +58 -0
  375. data/test/TC_Hybrid/doc/thing.txt +1 -0
  376. data/test/TC_Hybrid/iowa/Main.html +3 -0
  377. data/test/TC_Hybrid/iowa/Main.iwa +7 -0
  378. data/test/TC_Hybrid/iowa/NewPage.html +1 -0
  379. data/test/TC_Hybrid/iowa/NewPage.iwa +5 -0
  380. data/test/TC_Hybrid/iowa/app.cnf +10 -0
  381. data/test/TC_Hybrid/iowa/app.rb +5 -0
  382. data/test/TC_IOWAFunctions/doc/Ajax1.html +1 -0
  383. data/test/TC_IOWAFunctions/doc/Ajax1.iwa +1 -0
  384. data/test/TC_IOWAFunctions/doc/index.html +1 -0
  385. data/test/TC_IOWAFunctions/doc/js/dojo.js +9686 -0
  386. data/test/TC_IOWAFunctions/iowa/Ajax1.html +40 -0
  387. data/test/TC_IOWAFunctions/iowa/Ajax1.iwa +23 -0
  388. data/test/TC_IOWAFunctions/iowa/AjaxWidget.iwa +19 -0
  389. data/test/TC_IOWAFunctions/iowa/AjaxWidget.view +22 -0
  390. data/test/TC_IOWAFunctions/iowa/DanielTest.html +9 -0
  391. data/test/TC_IOWAFunctions/iowa/DanielTest.iwa +10 -0
  392. data/test/TC_IOWAFunctions/iowa/IntervalWidget.html +1 -0
  393. data/test/TC_IOWAFunctions/iowa/IntervalWidget.iwa +14 -0
  394. data/test/TC_IOWAFunctions/iowa/Main.html +1 -0
  395. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.html +12 -0
  396. data/test/TC_IOWAFunctions/iowa/NestedRepeat1.iwa +24 -0
  397. data/test/TC_IOWAFunctions/iowa/RPCResponse.iwa +7 -0
  398. data/test/TC_IOWAFunctions/iowa/RPCResponse.view +1 -0
  399. data/test/TC_IOWAFunctions/iowa/Repeat1.iwa +31 -0
  400. data/test/TC_IOWAFunctions/iowa/Repeat1.view +9 -0
  401. data/test/TC_IOWAFunctions/iowa/Repeat2.iwa +32 -0
  402. data/test/TC_IOWAFunctions/iowa/Repeat2.view +11 -0
  403. data/test/TC_IOWAFunctions/iowa/Repeat3.iwa +44 -0
  404. data/test/TC_IOWAFunctions/iowa/Repeat3.view +18 -0
  405. data/test/TC_IOWAFunctions/iowa/TesCon.html +1 -0
  406. data/test/TC_IOWAFunctions/iowa/TesCon.iwa +5 -0
  407. data/test/TC_IOWAFunctions/iowa/app.cnf +19 -0
  408. data/test/TC_IOWAFunctions/iowa/app.rb +9 -0
  409. data/test/TC_IOWAFunctions/iowa/mapfile.cnf +8 -0
  410. data/test/TC_ISAAC.rb +52 -0
  411. data/test/TC_ImageSize.rb +84 -0
  412. data/test/TC_ImageSize/img.bmp +0 -0
  413. data/test/TC_ImageSize/img.gif +0 -0
  414. data/test/TC_ImageSize/img.jpg +0 -0
  415. data/test/TC_ImageSize/img.pcx +0 -0
  416. data/test/TC_ImageSize/img.pgm +7144 -0
  417. data/test/TC_ImageSize/img.png +0 -0
  418. data/test/TC_ImageSize/img.ppm +0 -0
  419. data/test/TC_ImageSize/img.psd +0 -0
  420. data/test/TC_ImageSize/img.tiff +0 -0
  421. data/test/TC_ImageSize/img.xbm +22 -0
  422. data/test/TC_KeyValueCoding.rb +35 -0
  423. data/test/TC_LRUCache.rb +296 -0
  424. data/test/TC_LinkedList.rb +46 -0
  425. data/test/TC_Lockfile.rb +106 -0
  426. data/test/TC_Minimal.rb +45 -0
  427. data/test/TC_Minimal/app.cnf +8 -0
  428. data/test/TC_Minimal/cgi-bin/iowa.cgi +11 -0
  429. data/test/TC_Minimal/doc/index.html +1 -0
  430. data/test/TC_Minimal/iowa/Main.html +1 -0
  431. data/test/TC_Minimal/iowa/README +1 -0
  432. data/test/TC_Minimal/iowa/app.rb +3 -0
  433. data/test/TC_Minimal/webrick.rb +38 -0
  434. data/test/TC_Mongrel.rb +58 -0
  435. data/test/TC_Mongrel/doc/thing.txt +1 -0
  436. data/test/TC_Mongrel/iowa/Main.html +3 -0
  437. data/test/TC_Mongrel/iowa/Main.iwa +7 -0
  438. data/test/TC_Mongrel/iowa/NewPage.html +1 -0
  439. data/test/TC_Mongrel/iowa/NewPage.iwa +5 -0
  440. data/test/TC_Mongrel/iowa/app.cnf +10 -0
  441. data/test/TC_Mongrel/iowa/app.rb +5 -0
  442. data/test/TC_NoSubclass.rb +56 -0
  443. data/test/TC_NoSubclass/cgi/iowa.cgi +7 -0
  444. data/test/TC_NoSubclass/doc/index.html +1 -0
  445. data/test/TC_NoSubclass/iowa/Main.html +8 -0
  446. data/test/TC_NoSubclass/iowa/Main.iwa +14 -0
  447. data/test/TC_NoSubclass/iowa/README +1 -0
  448. data/test/TC_NoSubclass/iowa/app.cnf +8 -0
  449. data/test/TC_NoSubclass/iowa/app.rb +5 -0
  450. data/test/TC_NoSubclass/webrick.rb +38 -0
  451. data/test/TC_Pool.rb +139 -0
  452. data/test/TC_RenderedCache/doc/thing.txt +1 -0
  453. data/test/TC_RenderedCache/iowa/BigPage.html +1 -0
  454. data/test/TC_RenderedCache/iowa/BigPage.iwa +12 -0
  455. data/test/TC_RenderedCache/iowa/Main.html +3 -0
  456. data/test/TC_RenderedCache/iowa/Main.iwa +7 -0
  457. data/test/TC_RenderedCache/iowa/NewPage.html +1 -0
  458. data/test/TC_RenderedCache/iowa/NewPage.iwa +11 -0
  459. data/test/TC_RenderedCache/iowa/app.cnf +13 -0
  460. data/test/TC_RenderedCache/iowa/app.rb +5 -0
  461. data/test/TC_RenderedCache/iowa/mapfile.map +4 -0
  462. data/test/TC_ResourceURL.rb +73 -0
  463. data/test/TC_ResourceURL/iowa/Main.html +2 -0
  464. data/test/TC_ResourceURL/iowa/Main.iwa +10 -0
  465. data/test/TC_ResourceURL/iowa/app.cnf +10 -0
  466. data/test/TC_ResourceURL/iowa/app.rb +5 -0
  467. data/test/TC_SimpleDetached.rb +41 -0
  468. data/test/TC_StandardDispatcher.rb +362 -0
  469. data/test/TC_StandardDispatcherWithClassifier.rb +358 -0
  470. data/test/TC_String.rb +24 -0
  471. data/test/TC_Tag.rb +41 -0
  472. data/test/TC_Webrick.rb +56 -0
  473. data/test/TC_Webrick/doc/thing.txt +1 -0
  474. data/test/TC_Webrick/iowa/Main.html +3 -0
  475. data/test/TC_Webrick/iowa/Main.iwa +7 -0
  476. data/test/TC_Webrick/iowa/NewPage.html +1 -0
  477. data/test/TC_Webrick/iowa/NewPage.iwa +5 -0
  478. data/test/TC_Webrick/iowa/app.cnf +10 -0
  479. data/test/TC_Webrick/iowa/app.rb +5 -0
  480. data/test/tc_template.rb +15 -0
  481. data/test/tests.conf +19 -0
  482. data/utils/CVS/Entries +3 -0
  483. data/utils/CVS/Repository +1 -0
  484. data/utils/CVS/Root +1 -0
  485. data/utils/QuickCert-1.0.2.tar.gz +0 -0
  486. data/utils/QuickCert-1.0.2/InstalledFiles +7 -0
  487. data/utils/QuickCert-1.0.2/MANIFEST +10 -0
  488. data/utils/QuickCert-1.0.2/Makefile +15 -0
  489. data/utils/QuickCert-1.0.2/README +56 -0
  490. data/utils/QuickCert-1.0.2/bin/QuickCert +355 -0
  491. data/utils/QuickCert-1.0.2/config.save +12 -0
  492. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/README +60 -0
  493. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_c.rb +26 -0
  494. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/drbssl_s.rb +35 -0
  495. data/utils/QuickCert-1.0.2/data/examples/ruby/QuickCert/qc_config +21 -0
  496. data/utils/QuickCert-1.0.2/lib/QuickCert/defaults.rb +28 -0
  497. data/utils/QuickCert-1.0.2/setup.rb +1312 -0
  498. data/utils/iowa_apps +422 -0
  499. data/utils/smtp_sink.rb +9 -0
  500. data/utils/startup_template.cnf +27 -0
  501. data/utils/startup_template.rb +73 -0
  502. metadata +551 -0
@@ -0,0 +1,63 @@
1
+ module Iowa
2
+
3
+ # This is a subclass of Ruby's Hash that implements a few convenient
4
+ # methods used by IOWA.
5
+
6
+ class Hash < Hash
7
+
8
+ # A simple little routine to downcase any String used as a key
9
+ # in a hash or any hash nested as value somewhere within the hash.
10
+ # Thanks to Daniel Berger for this implementation.
11
+
12
+ def downcase_keys!
13
+ upper = /A-Z/
14
+ self.each do |k,v|
15
+ next unless k.kind_of? String
16
+ self[k.dup.downcase] = v
17
+ self.delete(k) if upper.match(k)
18
+ end
19
+ end
20
+
21
+ # Convert any symbolic keys to strings.
22
+
23
+ def stringify_keys!
24
+ self.each do |k,v|
25
+ next if k.kind_of? String
26
+ self[k.to_s] = v
27
+ self.delete k
28
+ end
29
+ end
30
+
31
+ def step_merge!(h)
32
+ h.each do |k,v|
33
+ if v.kind_of?(::Hash)
34
+ if self[k].kind_of?(::Hash)
35
+ unless self[k].respond_to?(:step_merge!)
36
+ if dp = self[k].default_proc
37
+ self[k] = Iowa::Hash.new {|h,k| dp.call(h,k)}.step_merge!(self[k])
38
+ else
39
+ osk = self[k]
40
+ self[k] = Iowa::Hash.new
41
+ self[k].step_merge!(osk)
42
+ end
43
+ end
44
+ self[k].step_merge!(v)
45
+ else
46
+ if self.default_proc
47
+ self.delete k
48
+ self[k]
49
+ end
50
+ unless self[k].kind_of?(::Hash)
51
+ self.delete k
52
+ self[k] = Iowa::Hash.new
53
+ end
54
+ self[k].step_merge!(v)
55
+ end
56
+ else
57
+ self[k] = v
58
+ end
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,575 @@
1
+ # The majority of code in this file comes from Ara Howard's lockfile.rb.
2
+ # http://rubyforge.org/project/codeforpeople
3
+ #
4
+ # This version is just trimmed and tweaked a bit differently, and has
5
+ # some code added so that it can use link() based locking, which is
6
+ # fairly portable and NFS safe, but does not work right on systems such
7
+ # as Windows XP, which do not return any sort of inode number to a
8
+ # stat call, or one can use flock() based locking, which works fairly
9
+ # portably, as well, but isn't a good choice for NFS.
10
+ #
11
+ # If the code is not told which method to use, it will conduct a
12
+ # couple tests intended to determine if the link() based locking will
13
+ # work. If it will, that is what it uses. Otherwise, it uses
14
+ # flock() based locking. It remembers the result of the test and
15
+ # automatically uses that as the default for future logfiles.
16
+
17
+ unless defined? $__lockfile__
18
+
19
+ require 'socket'
20
+ require 'timeout'
21
+ require 'fileutils'
22
+ require 'iowa/Constants'
23
+ require 'thread'
24
+
25
+ module Iowa
26
+
27
+ class Lockfile
28
+ class LockError < StandardError; end
29
+ class StolenLockError < LockError; end
30
+ class StackingLockError < LockError; end
31
+ class StatLockError < LockError; end
32
+ class MaxTriesLockError < LockError; end
33
+ class TimeoutLockError < LockError; end
34
+ class NFSLockError < LockError; end
35
+ class UnLockError < LockError; end
36
+
37
+ class SleepCycle < Array
38
+ attr :min
39
+ attr :max
40
+ attr :range
41
+ attr :inc
42
+
43
+ def initialize min, max, inc
44
+ @min, @max, @inc = Float(min), Float(max), Float(inc)
45
+ @range = @max - @min
46
+ raise RangeError, "max(#{ @max }) <= min(#{ @min })" if @max <= @min
47
+ raise RangeError, "inc(#{ @inc }) > range(#{ @range })" if @inc > @range
48
+ raise RangeError, "inc(#{ @inc }) <= 0" if @inc <= 0
49
+ raise RangeError, "range(#{ @range }) <= 0" if @range <= 0
50
+ s = @min
51
+ push(s) and s += @inc while(s <= @max)
52
+ self[-1] = @max if self[-1] < @max
53
+ reset
54
+ end
55
+
56
+ def next
57
+ ret = self[@idx]
58
+ @idx = ((@idx + 1) % self.size)
59
+ ret
60
+ end
61
+
62
+ def reset
63
+ @idx = 0
64
+ end
65
+ end
66
+
67
+ HOSTNAME = Socket::gethostname
68
+
69
+ UNKNOWN = Iowa::UnknownValue.instance
70
+ DEFAULT_RETRIES = nil # maximum number of attempts
71
+ DEFAULT_TIMEOUT = 30 # the longest we will try
72
+ DEFAULT_MAX_AGE = 1024 # lockfiles older than this are stale
73
+ DEFAULT_SLEEP_INC = 2 # sleep cycle is this much longer each time
74
+ DEFAULT_MIN_SLEEP = 2 # shortest sleep time
75
+ DEFAULT_MAX_SLEEP = 10 # longest sleep time
76
+ DEFAULT_SUSPEND = 15 # iff we steal a lock wait this long before we go on
77
+ DEFAULT_REFRESH = 8 # how often we touch/validate the lock
78
+ DEFAULT_DONT_CLEAN = false # iff we leave lock files lying around
79
+ DEFAULT_POLL_RETRIES = 16 # this many polls makes one 'try'
80
+ DEFAULT_POLL_MAX_SLEEP = 0.08 # the longest we'll sleep between polls
81
+ DEFAULT_DONT_SWEEP = false # if we cleanup after other process on our host
82
+ DEFAULT_DONT_USE_LOCK_ID = false # if we dump lock info into lockfile
83
+ DEFAULT_USE_FLOCK = Iowa::UnknownValue.instance # by default, try to figure it out
84
+
85
+
86
+ class << self
87
+ attr :retries, true
88
+ attr :max_age, true
89
+ attr :sleep_inc, true
90
+ attr :min_sleep, true
91
+ attr :max_sleep, true
92
+ attr :suspend, true
93
+ attr :timeout, true
94
+ attr :refresh, true
95
+ attr :dont_clean, true
96
+ attr :poll_retries, true
97
+ attr :poll_max_sleep, true
98
+ attr :dont_sweep, true
99
+ attr :dont_use_lock_id, true
100
+ attr :use_flock, true
101
+
102
+ def init
103
+ @retries = DEFAULT_RETRIES
104
+ @max_age = DEFAULT_MAX_AGE
105
+ @sleep_inc = DEFAULT_SLEEP_INC
106
+ @min_sleep = DEFAULT_MIN_SLEEP
107
+ @max_sleep = DEFAULT_MAX_SLEEP
108
+ @suspend = DEFAULT_SUSPEND
109
+ @timeout = DEFAULT_TIMEOUT
110
+ @refresh = DEFAULT_REFRESH
111
+ @dont_clean = DEFAULT_DONT_CLEAN
112
+ @poll_retries = DEFAULT_POLL_RETRIES
113
+ @poll_max_sleep = DEFAULT_POLL_MAX_SLEEP
114
+ @dont_sweep = DEFAULT_DONT_SWEEP
115
+ @dont_use_lock_id = DEFAULT_DONT_USE_LOCK_ID
116
+ @use_flock = DEFAULT_USE_FLOCK
117
+ end
118
+ end
119
+
120
+ self.init
121
+
122
+ attr :klass
123
+ attr :path
124
+ attr :opts
125
+ attr :locked
126
+ attr :thief
127
+ attr :dirname
128
+ attr :basename
129
+ attr :clean
130
+ attr :retries
131
+ attr :max_age
132
+ attr :sleep_inc
133
+ attr :min_sleep
134
+ attr :max_sleep
135
+ attr :suspend
136
+ attr :refresh
137
+ attr :timeout
138
+ attr :dont_clean
139
+ attr :poll_retries
140
+ attr :poll_max_sleep
141
+ attr :dont_sweep
142
+ attr :dont_use_lock_id
143
+ attr :use_flock
144
+
145
+ alias thief? thief
146
+ alias locked? locked
147
+
148
+ def self::create(path, *a, &b)
149
+ opts = {
150
+ 'retries' => 0,
151
+ 'min_sleep' => 0,
152
+ 'max_sleep' => 1,
153
+ 'sleep_inc' => 1,
154
+ 'max_age' => nil,
155
+ 'suspend' => 0,
156
+ 'refresh' => nil,
157
+ 'timeout' => nil,
158
+ 'poll_retries' => 0,
159
+ 'dont_clean' => true,
160
+ 'dont_sweep' => false,
161
+ 'dont_use_lock_id' => true,
162
+ 'use_flock' => false
163
+ }
164
+ begin
165
+ new(path, opts).lock
166
+ rescue LockError
167
+ raise Errno::EEXIST, path
168
+ end
169
+ open(path, *a, &b)
170
+ end
171
+
172
+ def initialize(path, opts = {}, &block)
173
+ @klass = self.class
174
+ @path = path
175
+ @opts = opts
176
+
177
+ @retries = getopt('retries') || @klass.retries
178
+ @max_age = getopt('max_age') || @klass.max_age
179
+ @sleep_inc = getopt('sleep_inc') || @klass.sleep_inc
180
+ @min_sleep = getopt('min_sleep') || @klass.min_sleep
181
+ @max_sleep = getopt('max_sleep') || @klass.max_sleep
182
+ @suspend = getopt('suspend') || @klass.suspend
183
+ @timeout = getopt('timeout') || @klass.timeout
184
+ @refresh = getopt('refresh') || @klass.refresh
185
+ @dont_clean = getopt('dont_clean') || @klass.dont_clean
186
+ @poll_retries = getopt('poll_retries') || @klass.poll_retries
187
+ @poll_max_sleep = getopt('poll_max_sleep') || @klass.poll_max_sleep
188
+ @dont_sweep = getopt('dont_sweep') || @klass.dont_sweep
189
+ @dont_use_lock_id = getopt('dont_use_lock_id') || @klass.dont_use_lock_id
190
+ @use_flock = getopt('use_flock') || @klass.use_flock
191
+
192
+ @sleep_cycle = SleepCycle::new @min_sleep, @max_sleep, @sleep_inc
193
+
194
+ @clean = @dont_clean ? nil : lambda{ File::unlink @path rescue nil }
195
+ @dirname = File::dirname @path
196
+ @basename = File::basename @path
197
+ @thief = false
198
+ @locked = false
199
+ @mutex = Mutex.new
200
+
201
+ lock(&block) if block
202
+ end
203
+
204
+ def lock
205
+ @mutex.synchronize do
206
+ if @use_flock == UNKNOWN
207
+ # Test to see if we should use flock by first stating a known file,
208
+ # and checking to see if an inode value is returned, and then by
209
+ # trying to create a test link in the lockfile path and seeing if
210
+ # that works. If either fails, use flock.
211
+ begin
212
+ known_stat = File::stat(__FILE__)
213
+ @use_flock = (known_stat.ino.to_i == 0)
214
+ rescue
215
+ @use_flock = true
216
+ end
217
+
218
+ unless @use_flock == true
219
+ begin
220
+ orig_file = tmpnam(@path,'orig_file')
221
+ link_file = tmpnam(@path,'link_file')
222
+ File.open(orig_file,'w+') {}
223
+ File::link(orig_file,link_file)
224
+ File::unlink orig_file
225
+ File::unlink link_file
226
+ @use_flock = false
227
+ rescue
228
+ @use_flock = true
229
+ end
230
+ end
231
+
232
+ self.class.use_flock = @use_flock
233
+ end
234
+
235
+ ret = nil
236
+
237
+ if @use_flock == true
238
+ begin
239
+ Timeout::timeout(@timeout) do
240
+ if block_given?
241
+ File.open(@path,'w+') do |fh|
242
+ fh.flock(File::LOCK_EX)
243
+ @locked = true
244
+ ret = yield @path
245
+ fh.flock(File::LOCK_UN)
246
+ @locked = false
247
+ end
248
+ return ret
249
+ else
250
+ @flock_fh = File.open(@path,'w+')
251
+ @flock_fh.flock(File::LOCK_EX)
252
+ @locked = true
253
+ return self
254
+ end
255
+ end
256
+ rescue
257
+ File::unlink @path if FileText.exist? @path
258
+ end
259
+ else
260
+ sweep unless @dont_sweep
261
+
262
+ attempt do
263
+ begin
264
+ @sleep_cycle.reset
265
+ create_tmplock do |f|
266
+ begin
267
+ Timeout::timeout(@timeout) do
268
+ tmp_path = f.path
269
+ tmp_stat = f.lstat
270
+ n_retries = 0
271
+ begin
272
+ i = 0
273
+ begin
274
+ begin
275
+ File::link tmp_path, @path
276
+ rescue Errno::ENOENT
277
+ try_again!
278
+ end
279
+ lock_stat = File::lstat @path
280
+ raise StatLockError, "stat's do not agree" unless
281
+ tmp_stat.rdev == lock_stat.rdev and tmp_stat.ino == lock_stat.ino
282
+ @locked = true
283
+ rescue => e
284
+ i += 1
285
+ unless i >= @poll_retries
286
+ t = [rand(@poll_max_sleep), @poll_max_sleep].min
287
+ sleep t
288
+ retry
289
+ end
290
+ raise
291
+ end
292
+
293
+ rescue => e
294
+ n_retries += 1
295
+ case validlock?
296
+ when true
297
+ raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
298
+ @retries and n_retries >= @retries
299
+ sleeptime = @sleep_cycle.next
300
+ sleep sleeptime
301
+ when false
302
+ begin
303
+ File::unlink @path
304
+ @thief = true
305
+ warn "<#{ @path }> stolen by <#{ Process.pid }> at <#{ timestamp }>"
306
+ rescue Errno::ENOENT
307
+ end
308
+ sleep @suspend
309
+ when nil
310
+ raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
311
+ @retries and n_retries >= @retries
312
+ end
313
+ retry
314
+ end # begin
315
+ end # timeout
316
+ rescue Timeout::Error
317
+ raise TimeoutLockError, "surpassed timeout <#{ @timeout }>"
318
+ end # begin
319
+ end # create_tmplock
320
+
321
+ if block_given?
322
+ stolen = false
323
+ refresher = (@refresh ? new_refresher : nil)
324
+ begin
325
+ begin
326
+ ret = yield @path
327
+ rescue StolenLockError
328
+ stolen = true
329
+ raise
330
+ end
331
+ ensure
332
+ begin
333
+ refresher.kill if refresher and refresher.status
334
+ ensure
335
+ unlock unless stolen
336
+ end
337
+ end
338
+ else
339
+ ObjectSpace.define_finalizer self, @clean if @clean
340
+ ret = self
341
+ end
342
+ rescue Errno::ESTALE, Errno::EIO => e
343
+ raise(NFSLockError, errmsg(e))
344
+ end
345
+ end
346
+
347
+ return ret
348
+ end
349
+ end
350
+ end
351
+
352
+ def sweep
353
+ begin
354
+ glob = File::join(@dirname, ".*lck")
355
+ paths = Dir[glob]
356
+ paths.each do |path|
357
+ begin
358
+ basename = File::basename path
359
+ pat = %r/^\s*\.([^_]+)_([^_]+)/o
360
+ if pat.match(basename)
361
+ host, pid = $1, $2
362
+ else
363
+ next
364
+ end
365
+ host.gsub!(%r/^\.+|\.+$/,'')
366
+ quad = host.split %r/\./
367
+ host = quad.first
368
+ pat = %r/^\s*#{ host }/i
369
+ if pat.match(HOSTNAME) and %r/^\s*\d+\s*$/.match(pid)
370
+ unless alive?(pid)
371
+ FileUtils::rm_f path
372
+ else
373
+ end
374
+ else
375
+ end
376
+ rescue
377
+ next
378
+ end
379
+ end
380
+ rescue => e
381
+ warn(errmsg(e))
382
+ end
383
+ end
384
+
385
+ def alive? pid
386
+ pid = Integer("#{ pid }")
387
+ begin
388
+ Process::kill 0, pid
389
+ true
390
+ rescue Errno::ESRCH
391
+ false
392
+ end
393
+ end
394
+
395
+ def unlock
396
+ raise UnLockError, "<#{ @path }> is not locked!" unless @locked
397
+ if @flock_fh
398
+ begin
399
+ @flock_fh.flock(File::LOCK_UN)
400
+ @flock_fh.close
401
+ File::unlink @path
402
+ rescue Errno::ENOENT
403
+ raise StolenLockError, @path
404
+ end
405
+ else
406
+ begin
407
+ File::unlink @path
408
+ rescue Errno::ENOENT
409
+ raise StolenLockError, @path
410
+ ensure
411
+ @thief = false
412
+ @locked = false
413
+ ObjectSpace.undefine_finalizer self if @clean
414
+ end
415
+ end
416
+ end
417
+
418
+ def new_refresher
419
+ Thread::new(Thread::current, @path, @refresh, @dont_use_lock_id) do |thread, path, refresh, dont_use_lock_id|
420
+ loop do
421
+ begin
422
+ touch path
423
+ unless dont_use_lock_id
424
+ loaded = load_lock_id(IO.read(path))
425
+ raise unless loaded == @lock_id
426
+ end
427
+ sleep refresh
428
+ rescue Exception => e
429
+ thread.raise StolenLockError
430
+ Thread::exit
431
+ end
432
+ end
433
+ end
434
+ end
435
+
436
+ def validlock?
437
+ if @max_age
438
+ uncache @path rescue nil
439
+ begin
440
+ return((Time.now - File::stat(@path).mtime) < @max_age)
441
+ rescue Errno::ENOENT
442
+ return nil
443
+ end
444
+ else
445
+ exist = File::exist?(@path)
446
+ return(exist ? true : nil)
447
+ end
448
+ end
449
+
450
+ def uncache file
451
+ refresh = nil
452
+ begin
453
+ is_a_file = File === file
454
+ path = (is_a_file ? file.path : file.to_s)
455
+ stat = (is_a_file ? file.stat : File::stat(file.to_s))
456
+ refresh = tmpnam(File::dirname(path))
457
+ File::link path, refresh
458
+ File::chmod stat.mode, path
459
+ File::utime stat.atime, stat.mtime, path
460
+ ensure
461
+ begin
462
+ File::unlink refresh if refresh
463
+ rescue Errno::ENOENT
464
+ end
465
+ end
466
+ end
467
+
468
+ def create_tmplock
469
+ tmplock = tmpnam @dirname
470
+ begin
471
+ create(tmplock) do |f|
472
+ unless dont_use_lock_id
473
+ @lock_id = gen_lock_id
474
+ dumped = dump_lock_id
475
+ f.write dumped
476
+ f.flush
477
+ end
478
+ yield f
479
+ end
480
+ ensure
481
+ begin; File::unlink tmplock; rescue Errno::ENOENT; end if tmplock
482
+ end
483
+ end
484
+
485
+ def gen_lock_id
486
+ Hash[
487
+ 'host' => "#{ HOSTNAME }",
488
+ 'pid' => "#{ Process.pid }",
489
+ 'ppid' => "#{ Process.ppid }",
490
+ 'time' => timestamp,
491
+ ]
492
+ end
493
+
494
+ def timestamp
495
+ time = Time.now
496
+ usec = time.usec.to_s
497
+ usec << '0' while usec.size < 6
498
+ "#{ time.strftime('%Y-%m-%d %H:%M:%S') }.#{ usec }"
499
+ end
500
+
501
+ def dump_lock_id lock_id = @lock_id
502
+ "host: %s\npid: %s\nppid: %s\ntime: %s\n" %
503
+ lock_id.values_at('host','pid','ppid','time')
504
+ end
505
+
506
+ def load_lock_id buf
507
+ lock_id = {}
508
+ kv = %r/([^:]+):(.*)/o
509
+ buf.each do |line|
510
+ m = kv.match line
511
+ k, v = m[1], m[2]
512
+ next unless m and k and v
513
+ lock_id[k.strip] = v.strip
514
+ end
515
+ lock_id
516
+ end
517
+
518
+ def tmpnam dir, seed = File::basename($0)
519
+ pid = Process.pid
520
+ time = Time.now
521
+ sec = time.to_i
522
+ usec = time.usec
523
+ "%s%s.%s_%d_%s_%d_%d_%d.lck" %
524
+ [dir, File::SEPARATOR, HOSTNAME, pid, seed, sec, usec, rand(sec)]
525
+ end
526
+
527
+ def create path
528
+ umask = nil
529
+ f = nil
530
+ begin
531
+ umask = File::umask 022
532
+ f = open path, File::WRONLY|File::CREAT|File::EXCL, 0644
533
+ ensure
534
+ File::umask umask if umask
535
+ end
536
+ return(block_given? ? begin; yield f; ensure; f.close; end : f)
537
+ end
538
+
539
+ def touch path
540
+ FileUtils.touch path
541
+ end
542
+
543
+ def getopt key
544
+ @opts[key] || @opts[key.to_s] || @opts[key.to_s.intern]
545
+ end
546
+
547
+ def to_str
548
+ @path
549
+ end
550
+ alias to_s to_str
551
+
552
+ def errmsg e
553
+ "%s (%s)\n%s\n" % [e.class, e.message, e.backtrace.join("\n")]
554
+ end
555
+
556
+ def attempt
557
+ ret = nil
558
+ loop{ break unless catch('attempt'){ ret = yield } == 'try_again' }
559
+ ret
560
+ end
561
+
562
+ def try_again!
563
+ throw 'attempt', 'try_again'
564
+ end
565
+ alias again! try_again!
566
+
567
+ def give_up!
568
+ throw 'attempt', 'give_up'
569
+ end
570
+ end
571
+
572
+ end
573
+
574
+ $__lockfile__ == __FILE__
575
+ end