--- /dev/null
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: shutter.h 1611 2006-08-20 14:48:55Z sleybo $\r
+ */\r
+\r
+\r
+#pragma once\r
+\r
+\r
+// Define the max numbers of operations that can be simultaniously done\r
+#define MAX_OPERATIONS 0x10000000\r
+\r
+typedef struct _shutter_t {\r
+ long cnt;\r
+ KEVENT event;\r
+\r
+} shutter_t;\r
+\r
+static inline void shutter_init(shutter_t* p_shutter)\r
+{\r
+ p_shutter->cnt = 0;\r
+ KeInitializeEvent( &p_shutter->event, SynchronizationEvent, FALSE );\r
+}\r
+\r
+\r
+static inline void shutter_sub(shutter_t * p_shutter,long Val)\r
+{\r
+ long res = 0;\r
+ ASSERT(Val < 0);\r
+ res = InterlockedExchangeAdd( &p_shutter->cnt,Val );\r
+ if ((res+Val) == -MAX_OPERATIONS)\r
+ KeSetEvent( &p_shutter->event, 0, FALSE );\r
+}\r
+\r
+// if RC == true, one can proceed\r
+static inline BOOLEAN shutter_add(shutter_t * p_shutter,long Val)\r
+{\r
+ long res = 0;\r
+ ASSERT(Val > 0);\r
+ res = InterlockedExchangeAdd(&p_shutter->cnt,Val); \r
+ ASSERT(res <= MAX_OPERATIONS);\r
+ if (res < 0 )\r
+ { \r
+ shutter_sub(p_shutter, -Val);\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+static inline void shutter_loose(shutter_t * p_shutter)\r
+{\r
+ long res = InterlockedDecrement( &p_shutter->cnt );\r
+ if (res == -MAX_OPERATIONS)\r
+ KeSetEvent( &p_shutter->event, 0, FALSE );\r
+}\r
+\r
+// if RC > 0, one can proceed\r
+static inline int shutter_use(shutter_t * p_shutter)\r
+{\r
+ long res = InterlockedIncrement( &p_shutter->cnt ); \r
+ ASSERT(res <= MAX_OPERATIONS);\r
+ if (res <= 0 ) \r
+ shutter_loose( p_shutter ); // The object is in shutdown\r
+ return res;\r
+}\r
+\r
+\r
+static inline void shutter_shut(shutter_t * p_shutter)\r
+{\r
+ long res = 0;\r
+ //\r
+ // ASSERT not calling shu twice.\r
+ //\r
+ ASSERT(p_shutter->cnt - MAX_OPERATIONS >= (-MAX_OPERATIONS));\r
+ \r
+ // Mark the counter as locked\r
+ res = InterlockedExchangeAdd(&p_shutter->cnt, -MAX_OPERATIONS);\r
+ ASSERT(res >= 0);\r
+ if (res) \r
+ // We are now waiting for the object to reach -MAX_OPERATIONS\r
+ KeWaitForSingleObject( &p_shutter->event, Executive, KernelMode, FALSE, NULL );\r
+}\r
+\r
+static inline void shutter_alive(shutter_t * p_shutter)\r
+{\r
+ long res = 0;\r
+ \r
+ // Mark the counter as alive\r
+ res = InterlockedExchangeAdd(&p_shutter->cnt, MAX_OPERATIONS);\r
+ ASSERT(res < 0);\r
+}\r
+\r
+\r