Replaced buggy ReactOS ERESOURCE handling by own single-threaded one.
authorshort <>
Sat, 13 Sep 2003 18:02:30 +0000 (18:02 +0000)
committershort <>
Sat, 13 Sep 2003 18:02:30 +0000 (18:02 +0000)
src/libcaptive/ex/Makefile.am
src/libcaptive/ex/resource.c [new file with mode: 0644]
src/libcaptive/reactos/ntoskrnl/ex/Makefile.am

index c3e1457..b6a4463 100644 (file)
@@ -23,5 +23,6 @@ noinst_LTLIBRARIES=libex.la
 libex_la_SOURCES= \
                list.c \
                lookas.c \
+               resource.c \
                time.c \
                work.c
diff --git a/src/libcaptive/ex/resource.c b/src/libcaptive/ex/resource.c
new file mode 100644 (file)
index 0000000..7780fb4
--- /dev/null
@@ -0,0 +1,340 @@
+/* $Id$
+ * reactos ERESOURCE handling by libcaptive
+ * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; exactly version 2 of June 1991 is required
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "config.h"
+
+#include "reactos/ddk/exfuncs.h"       /* self */
+#include <glib/gmessages.h>
+#include "reactos/ddk/extypes.h"       /* for ERESOURCE */
+#include "captive/macros.h"
+
+
+#define ERESOURCE_OWNING_COUNT_SHARED(Resource)    ((Resource)->OwnerThreads[0].a.OwnerCount)
+#define ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource) ((Resource)->OwnerThreads[1].a.OwnerCount)
+
+
+static gboolean PERESOURE_validate(PERESOURCE Resource)
+{
+       g_return_val_if_fail(Resource!=NULL,FALSE);
+
+       g_return_val_if_fail(Resource->ActiveCount
+                       ==ERESOURCE_OWNING_COUNT_SHARED(Resource)+ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource),FALSE);
+
+       return TRUE;
+}
+
+
+/**
+ * ExAcquireResourceExclusiveLite:
+ * @Resource: Resource to acquire for exclusive access.
+ * %NULL value is forbidden.
+ * @Wait: %TRUE if the caller may wait to acquire @Resource.
+ *
+ * Acquires a resource exclusively for the calling thread.
+ *
+ * Returns: %TRUE if the resource was acquired.
+ * libcaptive always returns %TRUE.
+ */
+BOOLEAN ExAcquireResourceExclusiveLite(PERESOURCE Resource,BOOLEAN Wait)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
+
+       Resource->ActiveCount++;
+       ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)++;
+
+       g_assert(PERESOURE_validate(Resource));
+       return TRUE;
+}
+
+
+/**
+ * ExAcquireResourceSharedLite:
+ * @Resource: Resource to acquire.
+ * %NULL value is forbidden.
+ * @Wait: %TRUE if the caller may wait to acquire @Resource.
+ *
+ * Shared acquire of resource for the calling thread.
+ *
+ * Returns: %TRUE if the resource was acquired.
+ * libcaptive always returns %TRUE.
+ */
+BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource,BOOLEAN Wait)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
+
+       Resource->ActiveCount++;
+       ERESOURCE_OWNING_COUNT_SHARED(Resource)++;
+
+       g_assert(PERESOURE_validate(Resource));
+       return TRUE;
+}
+
+
+/**
+ * ExConvertExclusiveToSharedLite:
+ * @Resource: Resource to convert access mode.
+ * %NULL value is forbidden.
+ *
+ * Converts a given resource from acquired for exclusive access to being
+ * acquired for shared access.
+ *
+ * You must already have exclusive access to @Resource before the call.
+ */
+VOID ExConvertExclusiveToSharedLite(PERESOURCE Resource)
+{
+       g_return_if_fail(PERESOURE_validate(Resource));
+       g_return_if_fail(ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)>0);
+
+       ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)--;
+       ERESOURCE_OWNING_COUNT_SHARED(Resource)++;
+
+       g_assert(PERESOURE_validate(Resource));
+}
+
+
+/**
+ * ExAcquireSharedStarveExclusive:
+ * @Resource: Resource to acquire for shared access.
+ * %NULL value is forbidden.
+ * @Wait: %TRUE if the caller should wait to acquire @Resource.
+ *
+ * Acquires a given resource for shared access. Current thread has priority
+ * over any threads currently wating for exclusive access to this @Resource.
+ *
+ * libcaptive has the same implementation as ExAcquireResourceSharedLite().
+ *
+ * Returns: %TRUE if the resource was acquired.
+ * libcaptive always returns %TRUE.
+ */
+BOOLEAN ExAcquireSharedStarveExclusive(PERESOURCE Resource,BOOLEAN Wait)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
+
+  return ExAcquireResourceSharedLite(Resource,Wait);
+}
+
+
+/**
+ * ExAcquireSharedWaitForExclusive:
+ * @Resource: Resource to acquire for shared access.
+ * %NULL value is forbidden.
+ * @Wait: %TRUE if the caller should wait to acquire @Resource.
+ *
+ * Acquires a given resource for shared access. Any threads currently wating
+ * for exclusive access to this @Resource have priority over the current
+ * thread.
+ *
+ * libcaptive has the same implementation as ExAcquireResourceSharedLite().
+ *
+ * Returns: %TRUE if the resource was acquired.
+ * libcaptive always returns %TRUE.
+ */
+BOOLEAN ExAcquireSharedWaitForExclusive(PERESOURCE Resource,BOOLEAN Wait)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
+
+  return ExAcquireResourceSharedLite(Resource,Wait);
+}
+
+
+/**
+ * ExReleaseResourceForThreadLite:
+ * @Resource: Resource to release.
+ * %NULL value is forbidden.
+ * @ResourceThreadId: Thread which currently owns @Resource.
+ * %NULL value is forbidden.
+ * Value ExGetCurrentResourceThread() required by libcaptive.
+ *
+ * Function releases @Resource. @ResourceThreadId must be either exclusive or
+ * shared owner of @Resource.
+ * FIXME: W32 undocumented: Ownership counter is decremented by 1;
+ * @ResourceThreadId may still own @Resource after this function finishes.
+ * FIXME: W32 undocumented: It is expected shared ownership should be released first.
+ * ntfs.sys of NT-5.1sp1 behaviour: Init,AcqExcl,AcqShared,Rel,expectExcl.
+ * Maybe acquire ordering also makes sense?
+ */
+VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,ERESOURCE_THREAD ResourceThreadId)
+{
+       g_return_if_fail(PERESOURE_validate(Resource));
+       g_return_if_fail(ResourceThreadId==ExGetCurrentResourceThread());
+       g_return_if_fail(Resource->ActiveCount>0);
+
+       /**/ if (ERESOURCE_OWNING_COUNT_SHARED(Resource)>0)
+               ERESOURCE_OWNING_COUNT_SHARED(Resource)--;
+       else if (ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)>0)
+               ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)--;
+       else g_assert_not_reached();
+
+       Resource->ActiveCount--;
+
+       g_assert(PERESOURE_validate(Resource));
+}
+
+
+/**
+ * ExReleaseResourceForThreadLite:
+ * @Resource: Resource to release.
+ * %NULL value is forbidden.
+ *
+ * Function releases @Resource. Current thread must be either exclusive or
+ * shared owner of @Resource.
+ * FIXME: W32 undocumented: Ownership counter is decremented by 1;
+ * Current thread may still own @Resource after this function finishes.
+ * FIXME: W32 undocumented: It is expected exclusive ownership should be released first.
+ */
+VOID ExReleaseResourceLite(PERESOURCE Resource)
+{
+       g_return_if_fail(PERESOURE_validate(Resource));
+
+  return ExReleaseResourceForThreadLite(Resource,ExGetCurrentResourceThread());
+}
+
+
+/**
+ * ExGetExclusiveWaiterCount:
+ * @Resource: Resource to query.
+ * %NULL value is forbidden.
+ *
+ * Reports the number of waiters for exclusive access.
+ *
+ * Returns: Number of waiters for exclusive access.
+ * This function always returns 0 by libcaptive.
+ */
+ULONG ExGetExclusiveWaiterCount(PERESOURCE Resource)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),0);
+
+       return 0;
+}
+
+
+/**
+ * ExGetSharedWaiterCount:
+ * @Resource: Resource to query.
+ * %NULL value is forbidden.
+ *
+ * Reports the number of currently pending waiters for shared access to
+ * @Resource.
+ *
+ * Returns: Number of waiters for shared access.
+ * This function always returns 0 by libcaptive.
+ */
+ULONG ExGetSharedWaiterCount(PERESOURCE Resource)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),0);
+
+       return 0;
+}
+
+
+/*
+ * ExIsResourceAcquiredExclusiveLite:
+ * @Resource: Resource to query.
+ * %NULL value is forbidden.
+ *
+ * Query if the calling thread owns exclusive access to @Resource.
+ *
+ * Returns: %TRUE if the caller has exclusive access to @Resource,
+ */
+BOOLEAN ExIsResourceAcquiredExclusiveLite(PERESOURCE Resource)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
+
+       return ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)>0;
+}
+
+
+/*
+ * ExIsResourceAcquiredSharedLite:
+ * @Resource: Resource to query.
+ * %NULL value is forbidden.
+ *
+ * Query if the calling thread owns shared access to @Resource.
+ * Exclusive access is considered equivalent to shared access in this case.
+ *
+ * Returns: Count how many times the caller owns @Resource for any access,
+ * Value 0 is returned if the resource is not owned at all.
+ */
+ULONG ExIsResourceAcquiredSharedLite(PERESOURCE Resource)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),0);
+
+       return Resource->ActiveCount;
+}
+
+
+/**
+ * ExInitializeResourceLite:
+ * @Resource: Memory block of size #PERESOURCE to initialize.
+ * %NULL value is forbidden.
+ *
+ * Initializes fields of #PERESOURCE structure.
+ *
+ * Returns: %STATUS_SUCCESS if the resource was initialized successfully.
+ * libcaptive always returns %STATUS_SUCCESS.
+ */
+NTSTATUS ExInitializeResourceLite(PERESOURCE Resource)
+{
+       g_return_val_if_fail(Resource!=NULL,STATUS_INVALID_PARAMETER);
+
+       CAPTIVE_MEMZERO(Resource);
+       KeInitializeSpinLock(&Resource->SpinLock);
+
+       g_assert(PERESOURE_validate(Resource));
+       return STATUS_SUCCESS;
+}
+
+
+/*
+ * ExReinitializeResourceLite:
+ * @Resource: Resource to reinitialize sized as #ERESOURCE.
+ * %NULL value is forbidden.
+ *
+ * Reinitialize data fields of @Resource. @Resource must be already initialized
+ * by ExInitializeResourceLite(). Its state is lost and it becomes a fresh new
+ * #ERESOURCED without any its owners.
+ */
+VOID ExReinitializeResourceLite(PERESOURCE Resource)
+{
+       g_return_if_fail(PERESOURE_validate(Resource));
+
+       ExDeleteResourceLite(Resource); /* errors ignored */
+       ExInitializeResourceLite(Resource);     /* errors ignored */
+}
+
+
+/**
+ * ExDeleteResourceLite:
+ * @Resource: Resource to delete.
+ * %NULL value is forbidden.
+ *
+ * Deletes any resources allocated for @Resource. Memory of #ERESOURCE pointer
+ * directly by @Resource is not freed - its storage belongs to the caller.
+ *
+ * This function is a NOP for libcaptive.
+ *
+ * Returns: %STATUS_SUCCESS if the resource was successfully deleted.
+ * libcaptive always returns %STATUS_SUCCESS.
+ */
+NTSTATUS ExDeleteResourceLite(PERESOURCE Resource)
+{
+       g_return_val_if_fail(PERESOURE_validate(Resource),STATUS_INVALID_PARAMETER);
+
+       return STATUS_SUCCESS;
+}
index 0d886fe..e913503 100644 (file)
@@ -24,6 +24,5 @@ include $(top_srcdir)/src/libcaptive/reactos/ntoskrnl/Makefile-ntoskrnl.am
 noinst_LTLIBRARIES=libex.la
 libex_la_SOURCES= \
                fmutex.c \
-               list.c \
-               resource.c
+               list.c
 BUILT_SOURCES+=$(libex_la_SOURCES)