harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r350181 [188/198] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/ depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/ depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/ depends/oss/win....
Date Thu, 01 Dec 2005 06:04:00 GMT
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,1007 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define CDEV_CURRENT_FUNCTION _comment_
+/**
+ * @file
+ * @ingroup Port
+ * @brief Shared Memory Semaphores
+ */
+#undef CDEV_CURRENT_FUNCTION
+
+#include <Windows.h>
+#include <shlobj.h>
+#include "hyport.h"
+#include "portpriv.h"
+#include "portnls.h"
+#include "ut_hyprt.h"
+
+#define CDEV_CURRENT_FUNCTION include_header
+#include "hyshmem.h"
+#undef CDEV_CURRENT_FUNCTION
+
+#define ENV_APPDATA "APPDATA"
+#define ENV_TEMP "TEMP"
+#define DIR_TEMP "C:\\TEMP"
+#define DIR_CROOT "C:\\"
+
+#define SUCCESS 0
+#define FAIL 1
+
+#define HYPORT_SHMEM_CREATIONMUTEX "hyshmemcreationMutex"
+#define HYPORT_SHMEM_WAITTIME (1000)	/* wait time in ms for creationMutex */
+
+#define CDEV_CURRENT_FUNCTION _prototypes_private
+static I_32 convertFileMapPerm (I_32 perm);
+static I_32 convertPerm (I_32 perm);
+static IDATA createDirectory (struct HyPortLibrary *portLibrary,
+			      char *pathname);
+static I_32 createMappedFile (struct HyPortLibrary *portLibrary,
+			      struct hyshmem_handle *handle);
+static void getNameFromSharedMemoryFileName (struct HyPortLibrary
+					     *portLibrary, char *buffer,
+					     UDATA size, const char *name);
+static char *getSharedMemoryFileName (struct HyPortLibrary *portLibrary,
+				      const char *rootName);
+static char *getSharedMemoryPathandFileName (struct HyPortLibrary
+					     *portLibrary,
+					     const char
+					     *sharedMemoryFileName);
+static IDATA ensureDirectory (struct HyPortLibrary *portLibrary);
+static I_32 findError (I_32 errorCode, I_32 errorCode2);
+static UDATA isSharedMemoryFileName (struct HyPortLibrary *portLibrary,
+				     const char *filename);
+static void convertSlash (char *pathname);
+static I_64 convertFileTimeToUnixEpoch (const FILETIME * time);
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_open
+/**
+ * Creates/open a shared memory region
+ * 
+ * The rootname will uniquely identify the shared memory region, 
+ * and is valid across different JVM instance. 
+ * 
+ * The shared memory region should persist across process, until OS reboots 
+ * or destroy call is being made.
+ * 
+ * @param[in] portLibrary The port Library
+ * @param[out] handle This handle is required for further attach/destroy of the memory region
+ * @param[in] rootname Shared name for the region, which used to identify the region. 
+ * @param[in] size Size of the region in bytes
+ * @param[in] perm permission for the region.
+ * 
+ * @return
+ * \arg HYPORT_ERROR_SHMEM_OPFAILED Failure - Cannot open the shared memory region
+ * \arg HYPORT_INFO_SHMEM_OPENED Success - Existing memory region has been opened
+ * \arg HYPORT_INFO_SHMEM_CREATED Success - A new shared memory region has been created
+ * 
+ */
+IDATA VMCALL
+hyshmem_open (struct HyPortLibrary *portLibrary,
+	      struct hyshmem_handle **handle, const char *rootname, I_32 size,
+	      I_32 perm)
+{
+  IDATA rc = HYPORT_ERROR_SHMEM_OPFAILED;
+  UDATA rootNameLength = 0;
+  DWORD waitResult;
+  struct hyshmem_handle *myHandle;
+
+  Trc_PRT_shmem_hyshmem_open_Entry (rootname, size, perm);
+  myHandle =
+    portLibrary->mem_allocate_memory (portLibrary,
+				      sizeof (struct hyshmem_handle));
+  if (NULL == myHandle)
+    {
+      Trc_PRT_shmem_hyshmem_open_Exit (HYPORT_ERROR_SHMEM_OPFAILED, myHandle);
+      return HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+
+  if (ensureDirectory (portLibrary) == FAIL)
+    {
+      Trc_PRT_shmem_hyshmem_open_Exit (HYPORT_ERROR_SHMEM_OPFAILED, myHandle);
+      return HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+
+  /* Create filename to open */
+  myHandle->rootName = getSharedMemoryFileName (portLibrary, rootname);
+  if (NULL == myHandle->rootName)
+    {
+      portLibrary->mem_free_memory (portLibrary, myHandle->rootName);
+      portLibrary->mem_free_memory (portLibrary, myHandle);
+      Trc_PRT_shmem_hyshmem_open_Exit (HYPORT_ERROR_SHMEM_OPFAILED, myHandle);
+      return HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+
+  /* Lock the creation mutex */
+  waitResult =
+    WaitForSingleObject (PPG_shmem_creationMutex, HYPORT_SHMEM_WAITTIME);
+  if (WAIT_TIMEOUT == waitResult)
+    {
+      portLibrary->mem_free_memory (portLibrary, myHandle->rootName);
+      portLibrary->mem_free_memory (portLibrary, myHandle);
+      Trc_PRT_shmem_hyshmem_open_Exit (HYPORT_ERROR_SHMEM_OPFAILED, myHandle);
+      return HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+
+#if defined(HYSHMEM_DEBUG)
+  portLibrary->tty_printf (portLibrary,
+			   "hyshmem_open: calling OpenFileMapping: %s\n",
+			   myHandle->rootName);
+#endif /* HYSHMEM_DEBUG */
+
+  /* copy all the flags into the handle, so that createMappedFile knows what to do */
+  myHandle->region = NULL;
+  myHandle->perm = perm;
+  myHandle->size = size;
+
+  /* First we would try to see whether we can open an existing File mapping, if we can use it */
+  myHandle->shmHandle =
+    OpenFileMapping (convertFileMapPerm (perm), FALSE, myHandle->rootName);
+  if (NULL == myHandle->shmHandle)
+    {
+      Trc_PRT_shmem_hyshmem_open_Event1 (myHandle->rootName);
+      if (HYPORT_ERROR_SHMEM_OPFAILED ==
+	  (rc = createMappedFile (portLibrary, myHandle)))
+	{
+	  portLibrary->mem_free_memory (portLibrary, myHandle->rootName);
+	  portLibrary->mem_free_memory (portLibrary, myHandle);
+	  Trc_PRT_shmem_hyshmem_open_Exit1 ();
+	}
+    }
+  else
+    {
+      Trc_PRT_shmem_hyshmem_open_Event2 (myHandle->rootName);
+      myHandle->mappedFile = 0;
+      rc = HYPORT_INFO_SHMEM_OPENED;
+    }
+
+  /* release the creation mutex */
+  ReleaseMutex (PPG_shmem_creationMutex);
+
+  if (HYPORT_ERROR_SHMEM_OPFAILED == rc)
+    {
+      portLibrary->file_error_message (portLibrary);
+      Trc_PRT_shmem_hyshmem_open_Exit1 ();
+    }
+  else
+    {
+      *handle = myHandle;
+      Trc_PRT_shmem_hyshmem_open_Exit (rc, myHandle);
+    }
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_attach
+/**
+ * Attaches the shared memory represented by the handle
+ * 
+ * @param[in] portLibrary The port Library
+ * @param[in] handle A valid shared memory handle
+ * 
+ * @return: A pointer to the shared memory region, NULL on failure
+ */
+void *VMCALL
+hyshmem_attach (struct HyPortLibrary *portLibrary,
+		struct hyshmem_handle *handle)
+{
+  Trc_PRT_shmem_hyshmem_attach_Entry (handle);
+
+  if (NULL != handle)
+    {
+      if (NULL != handle->region)
+	{
+	  Trc_PRT_shmem_hyshmem_attach_Exit (handle->region);
+	  return handle->region;
+	}
+      if (NULL != handle->shmHandle)
+	{
+	  I_32 permission = convertFileMapPerm (handle->perm);
+	  handle->region =
+	    MapViewOfFile (handle->shmHandle, permission, 0, 0, 0);
+	  if (NULL != handle->region)
+	    {
+	      Trc_PRT_shmem_hyshmem_attach_Exit (handle->region);
+	      return handle->region;
+	    }
+	  else
+	    {
+	      Trc_PRT_shmem_hyshmem_attach_Exit2 (GetLastError ());
+	    }
+	}
+    }
+
+  Trc_PRT_shmem_hyshmem_attach_Exit1 ();
+  return NULL;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_detach
+/**
+ * Detaches the shared memory region from the caller's process address space
+ * Use @ref hyshmem_destroy to actually remove the memory region from the Operating system
+ *
+ * @param[in] portLibrary the Port Library.
+ * @param[in] handle Pointer to the shared memory region.
+ * 
+ * @return 0 on success, -1 on failure.
+ */
+IDATA VMCALL
+hyshmem_detach (struct HyPortLibrary * portLibrary,
+		struct hyshmem_handle ** handle)
+{
+  Trc_PRT_shmem_hyshmem_detach_Entry (*handle);
+  if (NULL == (*handle)->region)
+    {
+      Trc_PRT_shmem_hyshmem_detach_Exit ();
+      return 0;
+    }
+
+  if (UnmapViewOfFile ((*handle)->region))
+    {
+      (*handle)->region = NULL;
+      Trc_PRT_shmem_hyshmem_detach_Exit ();
+      return 0;
+    }
+
+  Trc_PRT_shmem_hyshmem_detach_Exit1 ();
+  return -1;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_destroy
+/**
+ * Destroy and removes the shared memory region from OS.
+ * 
+ * The timing of which OS removes the memory is OS dependent. However when 
+ * you make a call you can considered that you can no longer access the region through
+ * the handle. Memory allocated for handle structure is freed as well.
+ * 
+ * @param[in] portLibrary The port Library
+ * @param[in] handle Pointer to a valid shared memory handle
+ * 
+ * @return 0 on success, -1 on failure.
+ */
+IDATA VMCALL
+hyshmem_destroy (struct HyPortLibrary * portLibrary,
+		 struct hyshmem_handle ** handle)
+{
+  IDATA rc = 0;
+  char *sharedMemoryMappedFile;
+
+  Trc_PRT_shmem_hyshmem_destroy_Entry (*handle);
+
+  sharedMemoryMappedFile =
+    getSharedMemoryPathandFileName (portLibrary, (*handle)->rootName);
+  if (NULL == sharedMemoryMappedFile)
+    {
+      return rc;
+    }
+
+  hyshmem_close (portLibrary, handle);
+
+  rc = portLibrary->file_unlink (portLibrary, sharedMemoryMappedFile);
+
+  Trc_PRT_shmem_hyshmem_destroy_Debug1 (sharedMemoryMappedFile, rc,
+					GetLastError ());
+
+  portLibrary->mem_free_memory (portLibrary, sharedMemoryMappedFile);
+
+  if (-1 == rc)
+    {
+      Trc_PRT_shmem_hyshmem_destroy_Exit1 ();
+    }
+  else
+    {
+      Trc_PRT_shmem_hyshmem_destroy_Exit ();
+    }
+
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_shutdown
+/**
+ * PortLibrary shutdown.
+ *
+ * This function is called during shutdown of the portLibrary.  Any resources that were created by @ref hyshsem_startup
+ * should be destroyed here.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @note Most implementations will be empty.
+ */
+void VMCALL
+hyshmem_shutdown (struct HyPortLibrary *portLibrary)
+{
+  if (PPG_shmem_directory != NULL)
+    {
+      portLibrary->mem_free_memory (portLibrary, PPG_shmem_directory);
+    }
+
+  CloseHandle (PPG_shmem_creationMutex);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_startup
+/**
+ * PortLibrary startup.
+ *
+ * This function is called during startup of the portLibrary.  Any resources that are required for
+ * the file operations may be created here.  All resources created here should be destroyed
+ * in @ref hyshsem_shutdown.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @return 0 on success, negative error code on failure.  Error code values returned are
+ * \arg HYPORT_ERROR_STARTUP_SHMEM
+ *
+ * @note Most implementations will simply return success.
+ */
+I_32 VMCALL
+hyshmem_startup (struct HyPortLibrary *portLibrary)
+{
+  /* Security attributes for the creationMutex is set to public accessible */
+  SECURITY_DESCRIPTOR secdes;
+  SECURITY_ATTRIBUTES secattr;
+
+  InitializeSecurityDescriptor (&secdes, SECURITY_DESCRIPTOR_REVISION);
+  SetSecurityDescriptorDacl (&secdes, TRUE, NULL, TRUE);
+
+  secattr.nLength = sizeof (SECURITY_ATTRIBUTES);
+  secattr.lpSecurityDescriptor = &secdes;
+  secattr.bInheritHandle = FALSE;
+
+  /* Initialise the creationMutex */
+  PPG_shmem_creationMutex =
+    CreateMutex (&secattr, FALSE, HYPORT_SHMEM_CREATIONMUTEX);
+  if (NULL == PPG_shmem_creationMutex)
+    {
+      if (GetLastError () == ERROR_ALREADY_EXISTS)
+	{
+	  PPG_shmem_creationMutex =
+	    OpenMutex (MUTEX_ALL_ACCESS, FALSE, HYPORT_SHMEM_CREATIONMUTEX);
+	  if (NULL == PPG_shmem_creationMutex)
+	    {
+	      return HYPORT_ERROR_STARTUP_SHMEM;
+	    }
+	}
+      else
+	{
+	  return HYPORT_ERROR_STARTUP_SHMEM;
+	}
+    }
+
+  /* make sure PPG_shmem_directory is null */
+  PPG_shmem_directory = NULL;
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_close
+/**
+ * Detach, Close and remove the shared memory handle.
+ * 
+ * @note This method does not remove the shared memory region from the OS
+ *	 use @ref hyshmem_destroy instead. However this will free all the memory
+ * resources used by the handle, and detach the region specified by the handle
+ *
+ * @param[in] portLibrary The port Library
+ * @param[in] handle Pointer to a valid shared memory handle
+ */
+void VMCALL
+hyshmem_close (struct HyPortLibrary *portLibrary,
+	       struct hyshmem_handle **handle)
+{
+  Trc_PRT_shmem_hyshmem_close_Entry (*handle);
+  hyshmem_detach (portLibrary, handle);
+  if (0 != (*handle)->mappedFile)
+    {
+      portLibrary->file_close (portLibrary, (*handle)->mappedFile);
+    }
+  CloseHandle ((*handle)->shmHandle);
+  portLibrary->mem_free_memory (portLibrary, (*handle)->rootName);
+  portLibrary->mem_free_memory (portLibrary, *handle);
+  *handle = NULL;
+  Trc_PRT_shmem_hyshmem_close_Exit ();
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_findclose
+/**
+ * Close the handle returned from @ref hyshmem_findfirst.
+ *
+ * @param[in] portLibrary The port library
+ * @param[in] findhandle  Handle returned from @ref hyshmem_findfirst.
+ */
+void VMCALL
+hyshmem_findclose (struct HyPortLibrary *portLibrary, UDATA findhandle)
+{
+  Trc_PRT_shmem_hyshmem_findclose_Entry (findhandle);
+  portLibrary->file_findclose (portLibrary, findhandle);
+  Trc_PRT_shmem_hyshmem_findclose_Exit ();
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_findfirst
+/**
+ * Find the name of a shared memory region on the system. Answers a handle
+ * to be used in subsequent calls to @ref hyshmem_findnext and @ref hyshmem_findclose. 
+ *
+ * @param[in] portLibrary The port library
+ * @param[out] resultbuf filename and path matching path.
+ *
+ * @return valid handle on success, -1 on failure.
+ */
+UDATA VMCALL
+hyshmem_findfirst (struct HyPortLibrary *portLibrary, char *resultbuf)
+{
+  UDATA findHandle;
+  char file[HyMaxPath];
+
+  Trc_PRT_shmem_hyshmem_findfirst_Entry ();
+
+  if (ensureDirectory (portLibrary) == FAIL)
+    {
+      return -1;
+    }
+
+  findHandle =
+    portLibrary->file_findfirst (portLibrary, PPG_shmem_directory, file);
+
+  if (findHandle == -1)
+    {
+      Trc_PRT_shmem_hyshmem_findfirst_Exit1 ();
+      return -1;
+    }
+
+  while (!isSharedMemoryFileName (portLibrary, file))
+    {
+      if (-1 == portLibrary->file_findnext (portLibrary, findHandle, file))
+	{
+	  portLibrary->file_findclose (portLibrary, findHandle);
+	  Trc_PRT_shmem_hyshmem_findfirst_Exit2 ();
+	  return -1;
+	}
+    }
+
+  getNameFromSharedMemoryFileName (portLibrary, resultbuf, HyMaxPath, file);
+  Trc_PRT_shmem_hyshmem_findfirst_Exit ();
+  return findHandle;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_findnext
+/**
+ * Find the name of the next shared memory region.
+ *
+ * @param[in] portLibrary The port library
+ * @param[in] findHandle handle returned from @ref hyshmem_findfirst.
+ * @param[out] resultbuf next filename and path matching findhandle.
+ *
+ * @return 0 on success, -1 on failure or if no matching entries.
+ */
+I_32 VMCALL
+hyshmem_findnext (struct HyPortLibrary * portLibrary, UDATA findHandle,
+		  char *resultbuf)
+{
+  char file[HyMaxPath];
+
+  Trc_PRT_shmem_hyshmem_findnext_Entry (findHandle);
+  if (portLibrary->file_findnext (portLibrary, findHandle, file) == -1)
+    {
+      Trc_PRT_shmem_hyshmem_findnext_Exit1 ();
+      return -1;
+    }
+
+  while (!isSharedMemoryFileName (portLibrary, file))
+    {
+      if (-1 == portLibrary->file_findnext (portLibrary, findHandle, file))
+	{
+	  Trc_PRT_shmem_hyshmem_findnext_Exit2 ();
+	  return -1;
+	}
+    }
+
+  getNameFromSharedMemoryFileName (portLibrary, resultbuf, HyMaxPath, file);
+  Trc_PRT_shmem_hyshmem_findnext_Exit ();
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshmem_stat
+/**
+ * Return the statistic for a shared memory region
+ *
+ * @note notice that the implementation can decided to put -1 in the fields of statbuf
+ * if it does not make sense on this platform, or it is impossible to obtain.
+ * 
+ * @param[in] portLibrary The port library
+ * @param[in] name The name of the shared memory area.
+ * @param[out] statbuf the statistics returns by the operating system
+ *
+ * @return 0 on success, -1 on failure or if there is no matching entries.
+ */
+UDATA VMCALL
+hyshmem_stat (struct HyPortLibrary * portLibrary, const char *name,
+	      struct HyPortShmemStatistic * statbuf)
+{
+  char *sharedMemoryFile;
+  HANDLE memHandle;
+  BY_HANDLE_FILE_INFORMATION FileInformation;
+
+  Trc_PRT_shmem_hyshmem_stat_Entry (name);
+  if (statbuf == NULL)
+    {
+      return -1;
+    }
+
+  statbuf->nattach = 0;
+
+  sharedMemoryFile = getSharedMemoryFileName (portLibrary, name);
+  memHandle = OpenFileMapping (FILE_MAP_READ, FALSE, sharedMemoryFile);
+
+  if (NULL == memHandle)
+    {
+      char *sharedMemoryFullPath;
+
+      sharedMemoryFullPath =
+	getSharedMemoryPathandFileName (portLibrary, sharedMemoryFile);
+      memHandle =
+	CreateFile (sharedMemoryFullPath, GENERIC_READ, 0, NULL,
+		    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+      if (NULL == memHandle)
+	{
+	  Trc_PRT_shmem_hyshmem_stat_Exit2 (sharedMemoryFullPath);
+	  portLibrary->mem_free_memory (portLibrary, sharedMemoryFullPath);
+	  portLibrary->mem_free_memory (portLibrary, sharedMemoryFile);
+	  CloseHandle (memHandle);
+	  return -1;
+	}
+
+      portLibrary->mem_free_memory (portLibrary, sharedMemoryFullPath);
+    }
+  else
+    {
+      /* If we can open the file mapping, it means that someone else is using the memory mapping,
+       * so we can assume there is at least 1 JVM attached to the memory area */
+      statbuf->nattach = 1;
+    }
+
+  portLibrary->mem_free_memory (portLibrary, sharedMemoryFile);
+
+  if (GetFileInformationByHandle (memHandle, &FileInformation) == 0)
+    {
+      /* We can't use GetFileInformationByHandle on shared memory handle, 
+         so just tell caller we can't do anything about it */
+
+      CloseHandle (memHandle);
+      statbuf->file = NULL;
+      statbuf->shmid = -1;
+      statbuf->atime = -1;
+      statbuf->dtime = -1;
+      statbuf->chtime = -1;
+      statbuf->perm = -1;
+      Trc_PRT_shmem_hyshmem_stat_Exit ();
+      return 0;
+    }
+
+  statbuf->file = NULL;
+  statbuf->shmid = -1;
+  statbuf->atime = -1;
+  statbuf->dtime =
+    convertFileTimeToUnixEpoch (&FileInformation.ftLastAccessTime);
+  statbuf->chtime =
+    convertFileTimeToUnixEpoch (&FileInformation.ftLastWriteTime);
+  statbuf->perm = -1;
+
+  CloseHandle (memHandle);
+  Trc_PRT_shmem_hyshmem_stat_Exit ();
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION convertPerm
+static I_32
+convertPerm (I_32 perm)
+{
+  /*FIXME: for now, just return PAGE_READWRITE.
+   * once we have defined our own permission flags we do the proper
+   * convert */
+  return PAGE_READWRITE;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION convertFileMapPerm
+static I_32
+convertFileMapPerm (I_32 perm)
+{
+  return FILE_MAP_ALL_ACCESS;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION convertSlash
+static void
+convertSlash (char *pathname)
+{
+  UDATA i;
+  UDATA length = strlen (pathname);
+
+  for (i = 0; i < length; i++)
+    {
+      if (pathname[i] == '\\')
+	{
+	  pathname[i] = '/';
+	}
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION createDirectory
+static IDATA
+createDirectory (struct HyPortLibrary *portLibrary, char *pathname)
+{
+  char tempPath[HYSH_MAXPATH];
+  char *current;
+
+  /* 
+   * TODO portlib mkdir does not takes permission, and does not return error code!
+   * try making it directly, if we can then do it and save ourselves running the loop
+   * also help detecting the case when the directory caller trying to make exist
+   */
+  if (0 == portLibrary->file_mkdir (portLibrary, pathname))
+    {
+      if (GetLastError () == ERROR_ALREADY_EXISTS)
+	{
+	  return 0;
+	}
+    }
+
+  portLibrary->str_printf (portLibrary, tempPath, HYSH_MAXPATH, "%s",
+			   pathname);
+
+  current = strchr (tempPath + 1, DIR_SEPARATOR);	/* skip the first '/' */
+
+  while (portLibrary->file_attr (portLibrary, pathname) != HyIsDir)
+    {
+      char *previous;
+
+      *current = '\0';
+
+#if defined(HYSHSEM_DEBUG)
+      portLibrary->tty_printf (portLibrary, "mkdir %s\n", tempPath);
+#endif
+
+      if (portLibrary->file_mkdir (portLibrary, tempPath))
+	{
+	  /* TODO: need a way of getting error code from file port lib! */
+	  if (GetLastError () != ERROR_ALREADY_EXISTS)
+	    {
+	      /* there is a geniune error, exit! */
+	      return errno;
+	    }
+	}
+
+      previous = current;
+      current = strchr (current + 1, DIR_SEPARATOR);
+      *previous = DIR_SEPARATOR;
+    }
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION createMappedFile
+/**
+ * @internal
+ * Creates a file in mapped memory
+ *
+ * @param[in] portLibrary The port library
+ * @param[in] handle the shared memory semaphore to be created
+ *
+ * @return HYPORT_ERROR_SHMEM_OPFAILED on failure, HYPORT_INFO_SHMEM_OPENED or HYPORT_INFO_SHMEM_CREATED on success
+ */
+static I_32
+createMappedFile (struct HyPortLibrary *portLibrary,
+		  struct hyshmem_handle *handle)
+{
+  I_32 rc;
+  char *shareMemoryFileName;
+
+  shareMemoryFileName =
+    getSharedMemoryPathandFileName (portLibrary, handle->rootName);
+  if (NULL == shareMemoryFileName)
+    {
+      return HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+
+#if defined(HYSHMEM_DEBUG)
+  portLibrary->tty_printf (portLibrary,
+			   "createMappedFile - trying to create Memory Mapped file = %s!\n",
+			   shareMemoryFileName);
+#endif /* HYSHMEM_DEBUG */
+
+  handle->mappedFile =
+    portLibrary->file_open (portLibrary, shareMemoryFileName,
+			    HyOpenCreateNew | HyOpenRead | HyOpenWrite, 0);
+  if (-1 == handle->mappedFile)
+    {
+#if defined(HYSHMEM_DEBUG)
+      portLibrary->tty_printf (portLibrary,
+			       "createMappedFile - createNew failed, so old file must be there!\n");
+#endif /*HYSHMEM_DEBUG */
+
+      /* CreateNew failed, it probably means that memory mapped file is there */
+      handle->mappedFile =
+	portLibrary->file_open (portLibrary, shareMemoryFileName,
+				HyOpenRead | HyOpenWrite, 0);
+      if (-1 == handle->mappedFile)
+	{
+#if defined(HYSHMEM_DEBUG)
+	  portLibrary->tty_printf (portLibrary,
+				   "createMappedFile - Opening existing file failed - weird!\n");
+#endif /*HYSHMEM_DEBUG */
+
+	  portLibrary->mem_free_memory (portLibrary, shareMemoryFileName);
+	  return HYPORT_ERROR_SHMEM_OPFAILED;
+	}
+      handle->size = 0;
+      rc = HYPORT_INFO_SHMEM_OPENED;
+    }
+  else
+    {
+      /* MoveFileEx allows us to delete the share caceh after the next reboot */
+      MoveFileEx (shareMemoryFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
+      rc = HYPORT_INFO_SHMEM_CREATED;
+    }
+
+  handle->shmHandle =
+    CreateFileMapping ((HANDLE) handle->mappedFile, NULL,
+		       convertPerm (handle->perm), 0, handle->size,
+		       handle->rootName);
+  if (NULL == handle->shmHandle)
+    {
+      /* Need to clean up the file */
+      portLibrary->file_close (portLibrary, handle->mappedFile);
+      portLibrary->file_unlink (portLibrary, shareMemoryFileName);
+
+#if defined(HYSHMEM_DEBUG)
+      portLibrary->tty_printf (portLibrary, "Error create file mapping\n");
+#endif /*HYSHMEM_DEBUG */
+
+      rc = HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+
+  portLibrary->mem_free_memory (portLibrary, shareMemoryFileName);
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION getSharedMemoryFileName
+static char *
+getSharedMemoryFileName (struct HyPortLibrary *portLibrary,
+			 const char *rootName)
+{
+  char sharedMemoryFile[HYSH_MAXPATH];
+  char *result;
+  char versionString[30];
+
+  GET_VERSION_STRING (portLibrary, versionString);
+
+  portLibrary->str_printf (portLibrary, sharedMemoryFile, HYSH_MAXPATH,
+			   "%s_%s", versionString, rootName);
+
+  result =
+    portLibrary->mem_allocate_memory (portLibrary,
+				      strlen (sharedMemoryFile) + 1);
+  if (NULL == result)
+    {
+      return NULL;
+    }
+
+  portLibrary->str_printf (portLibrary, result, strlen (sharedMemoryFile) + 1,
+			   sharedMemoryFile);
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION getSharedMemoryPathandFileName
+static char *
+getSharedMemoryPathandFileName (struct HyPortLibrary *portLibrary,
+				const char *sharedMemoryFileName)
+{
+  char *result;
+  UDATA resultLen;
+
+  /* the string is PPG_shm_directory\sharedMemoryFileName\0 */
+  resultLen =
+    strlen (sharedMemoryFileName) + strlen (PPG_shmem_directory) + 2;
+  result = portLibrary->mem_allocate_memory (portLibrary, resultLen);
+  if (NULL == result)
+    {
+      return NULL;
+    }
+
+  portLibrary->str_printf (portLibrary, result, resultLen, "%s\\%s",
+			   PPG_shmem_directory, sharedMemoryFileName);
+
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION getNameFromSharedMemoryFileName
+static void
+getNameFromSharedMemoryFileName (struct HyPortLibrary *portLibrary,
+				 char *buffer, UDATA size, const char *name)
+{
+  char versionString[30];
+  char *nameStart;
+
+  GET_VERSION_STRING (portLibrary, versionString);
+  nameStart = strstr (name, versionString);
+
+  if (NULL == nameStart)
+    {
+      return;
+    }
+
+  nameStart = nameStart + strlen (versionString) + 1;
+
+  portLibrary->str_printf (portLibrary, buffer, size, nameStart);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION isSharedMemoryFileName
+static UDATA
+isSharedMemoryFileName (struct HyPortLibrary *portLibrary,
+			const char *filename)
+{
+  char versionString[30];
+  GET_VERSION_STRING (portLibrary, versionString);
+
+  return NULL != strstr (filename, versionString);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION convertFileTimeToUnixEpoch
+static I_64
+convertFileTimeToUnixEpoch (const FILETIME * time)
+{
+  /*This function is copied from hyfile_lastmod */
+  I_64 tempResult, result;
+  tempResult =
+    ((I_64) time->dwHighDateTime << (I_64) 32) | (I_64) time->dwLowDateTime;
+
+  result = (tempResult - 116444736000000000) / 10000000;
+
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION ensureDirectory
+static IDATA
+ensureDirectory (struct HyPortLibrary *portLibrary)
+{
+  I_32 rc;
+  char *appdatadir;
+
+  /* Create the directory specified by the two environmet variables,
+   * If the environment variables are not found then  error
+   */
+  appdatadir =
+    portLibrary->mem_allocate_memory (portLibrary, HYSH_MAXPATH + 1);
+  if (NULL == appdatadir)
+    {
+      return FAIL;
+    }
+
+  rc = SHGetFolderPath (NULL, CSIDL_LOCAL_APPDATA, NULL, 0, appdatadir);
+  if (FAILED (rc))
+    {
+      /* The sequence for which we look for the shared memory directory:
+       * %APPDATA%, %TEMP%, c:\\temp, c:\\
+       */
+      if (-1 ==
+	  portLibrary->sysinfo_get_env (portLibrary, ENV_APPDATA, appdatadir,
+					HYSH_MAXPATH))
+	{
+	  if (-1 ==
+	      portLibrary->sysinfo_get_env (portLibrary, ENV_TEMP, appdatadir,
+					    HYSH_MAXPATH))
+	    {
+	      if (portLibrary->file_attr (portLibrary, DIR_TEMP) == HyIsDir)
+		{
+		  portLibrary->str_printf (portLibrary, appdatadir,
+					   HYSH_MAXPATH, DIR_TEMP);
+		}
+	      else
+		{
+		  portLibrary->str_printf (portLibrary, appdatadir,
+					   HYSH_MAXPATH, DIR_CROOT);
+		}
+	    }
+	}
+    }
+
+  portLibrary->str_printf (portLibrary, appdatadir, HYSH_MAXPATH, "%s\\%s",
+			   appdatadir, HYSH_BASEDIR);
+
+  Trc_PRT_shmem_hyshmem_ensureDirectory_path (appdatadir);
+
+  rc = portLibrary->file_attr (portLibrary, appdatadir);
+  switch (rc)
+    {
+    case HyIsFile:
+      break;
+    case HyIsDir:
+      PPG_shmem_directory = appdatadir;
+      return SUCCESS;
+    default:
+      if (0 == createDirectory (portLibrary, appdatadir))
+	{
+	  PPG_shmem_directory = appdatadir;
+	  return SUCCESS;
+	}
+    }
+  portLibrary->mem_free_memory (portLibrary, appdatadir);
+  return FAIL;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION findError
+/**
+ * @internal
+ * Determines the proper portable error code to return given a native error code
+ *
+ * @param[in] errorCode The error code reported by the OS
+ *
+ * @return	the (negative) portable error code
+ */
+static I_32
+findError (I_32 errorCode, I_32 errorCode2)
+{
+  switch (errorCode)
+    {
+    default:
+      return HYPORT_ERROR_SHMEM_OPFAILED;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshmem.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,56 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(hyshmem_h)
+#define hyshmem_h
+
+#include <Windows.h>
+
+typedef struct hyshmem_handle
+{
+  void *region;
+  char *rootName;
+  I_32 size;
+  IDATA mappedFile;
+  HANDLE shmHandle;
+  DWORD perm;
+  PROCESS_INFORMATION *helperpi;
+  BOOL creator;
+} hyshmem_handle;
+
+I_32 VMCALL hyshmem_startup (struct HyPortLibrary *portLibrary);
+IDATA VMCALL hyshmem_open (struct HyPortLibrary *portLibrary,
+			   struct hyshmem_handle **handle,
+			   const char *rootname, I_32 size, I_32 perm);
+void VMCALL hyshmem_close (struct HyPortLibrary *portLibrary,
+			   struct hyshmem_handle **handle);
+UDATA VMCALL hyshmem_findfirst (struct HyPortLibrary *portLibrary,
+				char *resultbuf);
+I_32 VMCALL hyshmem_findnext (struct HyPortLibrary *portLibrary,
+			      UDATA findHandle, char *resultbuf);
+UDATA VMCALL hyshmem_stat (struct HyPortLibrary *portLibrary,
+			   const char *name,
+			   struct HyPortShmemStatistic *statbuf);
+IDATA VMCALL hyshmem_destroy (struct HyPortLibrary *portLibrary,
+			      struct hyshmem_handle **handle);
+IDATA VMCALL hyshmem_detach (struct HyPortLibrary *portLibrary,
+			     struct hyshmem_handle **handle);
+void VMCALL hyshmem_findclose (struct HyPortLibrary *portLibrary,
+			       UDATA findhandle);
+void *VMCALL hyshmem_attach (struct HyPortLibrary *portLibrary,
+			     struct hyshmem_handle *handle);
+void VMCALL hyshmem_shutdown (struct HyPortLibrary *portLibrary);
+
+#endif /* hyshmem_h */

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,562 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define CDEV_CURRENT_FUNCTION _comment_
+/**
+ * @file
+ * @ingroup Port
+ * @brief Shared Semaphores
+ */
+#undef CDEV_CURRENT_FUNCTION
+
+#include <Windows.h>
+#include "hyport.h"
+#include "portpriv.h"
+#include "ut_hyprt.h"
+
+#define CDEV_CURRENT_FUNCTION include_header
+#include "hyshsem.h"
+#undef CDEV_CURRENT_FUNCTION
+
+#define HYPORT_SHSEM_CREATIONMUTEX "hyshsemcreationMutex"
+#define HYPORT_SHSEM_WAITTIME (2000)	/* wait time in ms for creationMutex */
+#define HYPORT_SHSEM_NAME_PREFIX "javasemaphore"
+
+/* Used Internally */
+#define DIR_SEP DIR_SEPARATOR
+
+#define OK 0
+#define SUCCESS 0
+
+#define CDEV_CURRENT_FUNCTION _prototypes_private
+IDATA createMutex (struct HyPortLibrary * portLibrary,
+		   struct hyshsem_handle * shsem_handle);
+static hyshsem_handle *createsemHandle (struct HyPortLibrary *portLibrary,
+					int nsems, char *baseName);
+IDATA openMutex (struct HyPortLibrary *portLibrary,
+		 struct hyshsem_handle *shsem_handle);
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_open
+/**
+ * Open an existing semaphore set, or create a new one if it does not exist
+ * 
+ * @param[in] portLibrary The port library.
+ * @param[out] handle A semaphore handle is allocated and initialised for use with further calls, NULL on failure.
+ * @param[in] semname Unique identifier of the semaphore.
+ * @param[in] setSize Size of the semaphore set.
+ * @param[in] permission Permission to the semaphore set.
+ *
+ * @return
+ * \arg HYPORT_ERROR_SHSEM_OPFAILED   Failure - Error opening the semaphore
+ * \arg HYPORT_INFO_SHSEM_CREATED Success - Semaphore has been created
+ * \arg HYPORT_INFO_SHSEM_OPENED  Success - Existing semaphore has been opened
+ * \arg HYPORT_INFO_SHSEM_SEMID_DIFF Success - Existing semaphore opened, but OS Semaphore key is different
+ */
+IDATA VMCALL
+hyshsem_open (struct HyPortLibrary *portLibrary,
+	      struct hyshsem_handle **handle, const char *semname,
+	      int setSize, int permission)
+{
+  /* TODO: what happens if setSize == 0? We used to allow the setSize to be 0 so that when the user trying to open
+     an existing semaphore they won't need to specify that. However because semaphore set is not part of Windows API
+     so we are emulating it using seperate name - we need code to find out how large a semaphore set is */
+  char baseFile[HYSH_MAXPATH], mutexName[HYSH_MAXPATH];
+  char versionStr[32];
+  hyshsem_handle *shsem_handle;
+  I_32 rc;
+  DWORD waitResult;
+
+  Trc_PRT_shsem_hyshsem_open_Entry (semname, setSize, permission);
+  GET_VERSION_STRING (portLibrary, versionStr);
+
+  portLibrary->str_printf (portLibrary, baseFile, HYSH_MAXPATH, "%s%s_%s",
+			   HYPORT_SHSEM_NAME_PREFIX, versionStr, semname);
+
+  shsem_handle = (*handle) = createsemHandle (portLibrary, setSize, baseFile);
+  if (!shsem_handle)
+    {
+      return HYPORT_ERROR_SHSEM_OPFAILED;
+    }
+
+  Trc_PRT_shsem_hyshsem_open_Debug1 (baseFile);
+
+  /* Lock the creation mutex */
+  waitResult =
+    WaitForSingleObject (PPG_shsem_creationMutex, HYPORT_SHSEM_WAITTIME);
+  if (WAIT_TIMEOUT == waitResult)
+    {
+      portLibrary->mem_free_memory (portLibrary, (*handle)->rootName);
+      portLibrary->mem_free_memory (portLibrary, (*handle)->semHandles);
+      portLibrary->mem_free_memory (portLibrary, *handle);
+      *handle = NULL;
+      return HYPORT_ERROR_SHSEM_OPFAILED;
+    }
+
+  /*First try and see whether the main mutex exists */
+  portLibrary->str_printf (portLibrary, mutexName, HYSH_MAXPATH, "%s",
+			   baseFile);
+  shsem_handle->mainLock = OpenMutex (MUTEX_ALL_ACCESS, FALSE, mutexName);
+
+  if (shsem_handle->mainLock == NULL)
+    {
+      Trc_PRT_shsem_hyshsem_open_Event1 (mutexName);
+      rc = createMutex (portLibrary, shsem_handle);
+    }
+  else
+    {
+      Trc_PRT_shsem_hyshsem_open_Event2 (mutexName);
+      rc = openMutex (portLibrary, shsem_handle);
+    }
+
+  /* release the creation mutex */
+  ReleaseMutex (PPG_shsem_creationMutex);
+
+  if (HYPORT_ERROR_SHSEM_OPFAILED == rc)
+    {
+      Trc_PRT_shsem_hyshsem_open_Exit1 ();
+      portLibrary->file_error_message (portLibrary);
+      return rc;
+    }
+
+  Trc_PRT_shsem_hyshsem_open_Exit (rc, (*handle));
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_post
+/**
+ * post operation increments the counter in the semaphore by 1 if there is no one in wait for the semaphore. 
+ * if there are other processes suspended by wait then one of them will become runnable and 
+ * the counter remains the same. 
+ * 
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Semaphore set handle.
+ * @param[in] semset The no of semaphore in the semaphore set that you want to post.
+ * @param[in] flag The semaphore operation flag:
+ * \arg HYPORT_SHSEM_MODE_DEFAULT The default operation flag, same as 0
+ * \arg HYPORT_SHSEM_MODE_UNDO The changes made to the semaphore will be undone when this process finishes.
+ *
+ * @return 0 on success, -1 on failure.
+ */
+IDATA VMCALL
+hyshsem_post (struct HyPortLibrary * portLibrary,
+	      struct hyshsem_handle * handle, UDATA semset, UDATA flag)
+{
+  Trc_PRT_shsem_hyshsem_post_Entry (handle, semset, flag);
+  /* flag is ignored on Win32 for now - there is no Undo for semaphore */
+  if (handle == NULL)
+    {
+      Trc_PRT_shsem_hyshsem_post_Exit1 ();
+      return HYPORT_ERROR_SHSEM_HANDLE_INVALID;
+    }
+
+  if (semset < 0 || semset >= handle->setSize)
+    {
+      Trc_PRT_shsem_hyshsem_post_Exit2 ();
+      return HYPORT_ERROR_SHSEM_SEMSET_INVALID;
+    }
+
+  if (ReleaseMutex (handle->semHandles[semset]))
+    {
+      Trc_PRT_shsem_hyshsem_post_Exit (0);
+      return 0;
+    }
+  else
+    {
+      Trc_PRT_shsem_hyshsem_post_Exit3 (0, GetLastError ());
+      return -1;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_wait
+/**
+ * Wait operation decrements the counter in the semaphore set if the counter > 0
+ * if counter == 0 then the caller will be suspended.
+ * 
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Semaphore set handle.
+ * @param[in] semset The no of semaphore in the semaphore set that you want to post.
+ * @param[in] flag The semaphore operation flag:
+ * \arg HYPORT_SHSEM_MODE_DEFAULT The default operation flag, same as 0
+ * \arg HYPORT_SHSEM_MODE_UNDO The changes made to the semaphore will be undone when this process finishes.
+ * \arg HYPORT_SHSEM_MODE_NOWAIT The caller will not be suspended if sem == 0, a -1 is returned instead.
+ * 
+ * @return 0 on success, -1 on failure.
+ */
+IDATA VMCALL
+hyshsem_wait (struct HyPortLibrary * portLibrary,
+	      struct hyshsem_handle * handle, UDATA semset, UDATA flag)
+{
+  DWORD timeout, rc;
+
+  Trc_PRT_shsem_hyshsem_wait_Entry (handle, semset, flag);
+
+  if (handle == NULL)
+    {
+      Trc_PRT_shsem_hyshsem_wait_Exit1 ();
+      return HYPORT_ERROR_SHSEM_HANDLE_INVALID;
+    }
+  if (semset < 0 || semset >= handle->setSize)
+    {
+      Trc_PRT_shsem_hyshsem_wait_Exit2 ();
+      return HYPORT_ERROR_SHSEM_SEMSET_INVALID;
+    }
+
+  if (flag & HYPORT_SHSEM_MODE_NOWAIT)
+    {
+      timeout = 0;
+    }
+  else
+    {
+      timeout = INFINITE;
+    }
+
+  rc = WaitForSingleObject (handle->semHandles[semset], timeout);
+
+  switch (rc)
+    {
+    case WAIT_ABANDONED:	/* This means someone has crash but hasn't relase the mutex, we are okay with this */
+    case WAIT_OBJECT_0:
+      Trc_PRT_shsem_hyshsem_wait_Exit (0);
+      return 0;
+    case WAIT_TIMEOUT:		/* Falls through */
+    case WAIT_FAILED:
+      Trc_PRT_shsem_hyshsem_wait_Exit3 (-1, rc);
+      return -1;
+    default:
+      Trc_PRT_shsem_hyshsem_wait_Exit3 (-1, rc);
+      return -1;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_getVal
+/**
+ * reading the value of the semaphore in the set. This function
+ * uses no synchronisation prmitives
+  * 
+ * @pre caller has to deal with synchronisation issue.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Semaphore set handle.
+ * @param[in] semset The number of semaphore in the semaphore set that you want to post.
+ * 
+ * @return -1 on failure, the value of the semaphore on success
+ * 
+ * @warning: The user will need to make sure locking is done correctly when
+ * accessing semaphore values. This is because getValue simply reads the semaphore
+ * value without stopping the access to the semaphore. Therefore the value of the semaphore
+ * can change before the function returns. 
+ */
+IDATA VMCALL
+hyshsem_getVal (struct HyPortLibrary * portLibrary,
+		struct hyshsem_handle * handle, UDATA semset)
+{
+  Trc_PRT_shsem_hyshsem_getVal_Entry (*handle, semset);
+  Trc_PRT_shsem_hyshsem_getVal_Exit (0);
+  return -1;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_setVal
+/**
+ * 
+ * setting the value of the semaphore specified in semset. This function
+ * uses no synchronisation prmitives
+ * 
+ * @pre Caller has to deal with synchronisation issue.
+ * 
+ * @param[in] portLibrary The port Library.
+ * @param[in] handle Semaphore set handle.
+ * @param[in] semset The no of semaphore in the semaphore set that you want to post.
+ * @param[in] value The value that you want to set the semaphore to
+ * 
+ * @warning The user will need to make sure locking is done correctly when
+ * accessing semaphore values. This is because setValue simply set the semaphore
+ * value without stopping the access to the semaphore. Therefore the value of the semaphore
+ * can change before the function returns. 
+ *
+ * @return 0 on success, -1 on failure.
+ */
+IDATA VMCALL
+hyshsem_setVal (struct HyPortLibrary * portLibrary,
+		struct hyshsem_handle * handle, UDATA semset, IDATA value)
+{
+  Trc_PRT_shsem_hyshsem_setVal_Entry (handle, semset, value);
+  Trc_PRT_shsem_hyshsem_setVal_Exit (-1);
+  return -1;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_close
+/**
+ * Release the resources allocated for the semaphore handles.
+ * 
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Semaphore set handle.
+ * 
+ * @note The actual semaphore is not destroyed.  Once the close operation has been performed 
+ * on the semaphore handle, it is no longer valid and user needs to reissue @ref hyshsem_open call.
+ */
+void VMCALL
+hyshsem_close (struct HyPortLibrary *portLibrary,
+	       struct hyshsem_handle **handle)
+{
+  U_32 i;
+  hyshsem_handle *sem_handle = (*handle);
+
+  Trc_PRT_shsem_hyshsem_close_Entry (*handle);
+
+  if (*handle == NULL)
+    {
+      return;
+    }
+
+  for (i = 0; i < sem_handle->setSize; i++)
+    {
+      CloseHandle (sem_handle->semHandles[i]);
+    }
+
+  CloseHandle (sem_handle->mainLock);
+
+  portLibrary->mem_free_memory (portLibrary, (*handle)->rootName);
+  portLibrary->mem_free_memory (portLibrary, (*handle)->semHandles);
+  portLibrary->mem_free_memory (portLibrary, *handle);
+  *handle = NULL;
+
+  Trc_PRT_shsem_hyshsem_close_Exit ();
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_destroy
+/**
+ * Destroy the semaphore and release the resources allocated for the semaphore handles.
+ * 
+ * @param[in] portLibrary The port library.
+ * @param[in] handle Semaphore set handle.
+ * 
+ * @return 0 on success, -1 on failure.
+ * @note Due to operating system restriction we may not be able to destroy the semaphore
+ */
+IDATA VMCALL
+hyshsem_destroy (struct HyPortLibrary *portLibrary,
+		 struct hyshsem_handle **handle)
+{
+  Trc_PRT_shsem_hyshsem_destroy_Entry (*handle);
+  /*On Windows this just maps to hyshsem_close */
+  if ((*handle) == NULL)
+    {
+      return 0;
+    }
+
+  hyshsem_close (portLibrary, handle);
+  Trc_PRT_shsem_hyshsem_close_Exit ();
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_startup
+/**
+ * PortLibrary startup.
+ *
+ * This function is called during startup of the portLibrary.  Any resources that are required for
+ * the file operations may be created here.  All resources created here should be destroyed
+ * in @ref hyshsem_shutdown.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @return 0 on success, negative error code on failure.  Error code values returned are
+ * \arg HYPORT_ERROR_STARTUP_SHSEM
+ *
+ * @note Most implementations will simply return success.
+ */
+I_32 VMCALL
+hyshsem_startup (struct HyPortLibrary * portLibrary)
+{
+  /* Security attributes for the creationMutex is set to public accessible */
+  SECURITY_DESCRIPTOR secdes;
+  SECURITY_ATTRIBUTES secattr;
+
+  InitializeSecurityDescriptor (&secdes, SECURITY_DESCRIPTOR_REVISION);
+  SetSecurityDescriptorDacl (&secdes, TRUE, NULL, TRUE);
+
+  secattr.nLength = sizeof (SECURITY_ATTRIBUTES);
+  secattr.lpSecurityDescriptor = &secdes;
+  secattr.bInheritHandle = FALSE;
+
+  /* Initialise the creationMutex */
+  PPG_shsem_creationMutex =
+    CreateMutex (&secattr, FALSE, HYPORT_SHSEM_CREATIONMUTEX);
+  if (NULL == PPG_shsem_creationMutex)
+    {
+      if (GetLastError () == ERROR_ALREADY_EXISTS)
+	{
+	  PPG_shsem_creationMutex =
+	    OpenMutex (MUTEX_ALL_ACCESS, FALSE, HYPORT_SHSEM_CREATIONMUTEX);
+	  if (NULL == PPG_shsem_creationMutex)
+	    {
+	      return HYPORT_ERROR_STARTUP_SHSEM;
+	    }
+	}
+      else
+	{
+	  return HYPORT_ERROR_STARTUP_SHSEM;
+	}
+    }
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hyshsem_shutdown
+/**
+ * PortLibrary shutdown.
+ *
+ * This function is called during shutdown of the portLibrary.  Any resources that were created by @ref hyshsem_startup
+ * should be destroyed here.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @note Most implementations will be empty.
+ */
+void VMCALL
+hyshsem_shutdown (struct HyPortLibrary *portLibrary)
+{
+  CloseHandle (PPG_shsem_creationMutex);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION createsemHandle
+static hyshsem_handle *
+createsemHandle (struct HyPortLibrary *portLibrary, int nsems, char *baseName)
+{
+  hyshsem_handle *result;
+
+  result =
+    portLibrary->mem_allocate_memory (portLibrary, sizeof (hyshsem_handle));
+  if (result == NULL)
+    {
+      return NULL;
+    }
+
+  result->rootName =
+    portLibrary->mem_allocate_memory (portLibrary, strlen (baseName) + 1);
+  if (result->rootName == NULL)
+    {
+      portLibrary->mem_free_memory (portLibrary, result);
+      return NULL;
+    }
+  portLibrary->str_printf (portLibrary, result->rootName, HYSH_MAXPATH, "%s",
+			   baseName);
+
+  /*Allocating semHandle array */
+  result->semHandles =
+    portLibrary->mem_allocate_memory (portLibrary, nsems * sizeof (HANDLE));
+  if (result->semHandles == NULL)
+    {
+      portLibrary->mem_free_memory (portLibrary, result->rootName);
+      portLibrary->mem_free_memory (portLibrary, result);
+      return NULL;
+    }
+
+  result->setSize = nsems;
+
+  /* TODO: need to check whether baseName is too long - what should we do if it is?! */
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION createSemaphore
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION openSemaphore
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION createMutex
+IDATA
+createMutex (struct HyPortLibrary * portLibrary,
+	     struct hyshsem_handle * shsem_handle)
+{
+  U_32 i;
+  char mutexName[HYSH_MAXPATH];
+
+  shsem_handle->mainLock = CreateMutex (NULL, TRUE, shsem_handle->rootName);
+  if (shsem_handle->mainLock == NULL)
+    {
+      /* can't create mainlock, we can't do anything else :-( */
+      return HYPORT_ERROR_SHSEM_OPFAILED;
+    }
+
+  for (i = 0; i < shsem_handle->setSize; i++)
+    {
+      HANDLE debugHandle;
+      portLibrary->str_printf (portLibrary, mutexName, HYSH_MAXPATH,
+			       "%s_set%d", shsem_handle->rootName, i);
+
+      debugHandle = shsem_handle->semHandles[i] =
+	CreateMutex (NULL, TRUE, mutexName);
+      if (shsem_handle->semHandles[i] == NULL)
+	{
+	  return HYPORT_ERROR_SHSEM_OPFAILED;
+	}
+    }
+
+  return HYPORT_INFO_SHSEM_CREATED;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION openMutex
+IDATA
+openMutex (struct HyPortLibrary * portLibrary,
+	   struct hyshsem_handle * shsem_handle)
+{
+  /*Open and setup the mutex arrays */
+  U_32 i;
+  char mutexName[HYSH_MAXPATH];
+
+  for (i = 0; i < shsem_handle->setSize; i++)
+    {
+      portLibrary->str_printf (portLibrary, mutexName, HYSH_MAXPATH,
+			       "%s_set%d", shsem_handle->rootName, i);
+
+      shsem_handle->semHandles[i] =
+	OpenMutex (MUTEX_ALL_ACCESS, FALSE, mutexName);
+      if (shsem_handle->semHandles[i] == NULL)
+	{
+	  U_32 j;
+	  for (j = 0; j < i; j++)
+	    {
+	      CloseHandle (shsem_handle->semHandles[i]);
+	    }
+	  return HYPORT_ERROR_SHSEM_OPFAILED;
+	}
+    }
+
+  return HYPORT_INFO_SHSEM_OPENED;
+}
+
+#undef CDEV_CURRENT_FUNCTION

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hyshsem.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,51 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(hyshsem_h)
+#define hyshsem_h
+
+#include "portpriv.h"
+
+typedef struct hyshsem_handle
+{
+  char *rootName;
+  HANDLE *semHandles;
+  HANDLE *mainLock;
+  U_32 setSize;
+  BOOL creator;
+} hyshsem_handle;
+
+I_32 VMCALL hyshsem_startup (struct HyPortLibrary *portLibrary);
+void VMCALL hyshsem_close (struct HyPortLibrary *portLibrary,
+			   struct hyshsem_handle **handle);
+IDATA VMCALL hyshsem_post (struct HyPortLibrary *portLibrary,
+			   struct hyshsem_handle *handle, UDATA semset,
+			   UDATA flag);
+IDATA VMCALL hyshsem_destroy (struct HyPortLibrary *portLibrary,
+			      struct hyshsem_handle **handle);
+void VMCALL hyshsem_shutdown (struct HyPortLibrary *portLibrary);
+IDATA VMCALL hyshsem_setVal (struct HyPortLibrary *portLibrary,
+			     struct hyshsem_handle *handle, UDATA semset,
+			     IDATA value);
+IDATA VMCALL hyshsem_open (struct HyPortLibrary *portLibrary,
+			   struct hyshsem_handle **handle,
+			   const char *semname, int setSize, int permission);
+IDATA VMCALL hyshsem_getVal (struct HyPortLibrary *portLibrary,
+			     struct hyshsem_handle *handle, UDATA semset);
+IDATA VMCALL hyshsem_wait (struct HyPortLibrary *portLibrary,
+			   struct hyshsem_handle *handle, UDATA semset,
+			   UDATA flag);
+
+#endif /* hyshsem_h */

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,782 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <windows.h>
+#include <stdlib.h>
+#include "hyport.h"
+#include "hythread.h"
+#include "hysignal.h"
+
+typedef struct HyWin32AsyncHandlerRecord
+{
+  HyPortLibrary *portLib;
+  hysig_handler_fn handler;
+  void *handler_arg;
+  U_32 flags;
+  struct HyWin32AsyncHandlerRecord *next;
+} HyWin32AsyncHandlerRecord;
+
+static HyWin32AsyncHandlerRecord *asyncHandlerList;
+static hythread_monitor_t asyncMonitor;
+static U_32 asyncThreadCount;
+static U_32 attachedPortLibraries;
+/* holds the options set by hysig_set_options */
+static U_32 signalOptions;
+
+#define CDEV_CURRENT_FUNCTION _prototypes_private
+
+static U_32 mapWin32ExceptionToPortlibType (U_32 exceptionCode);
+
+static U_32 infoForGPR (struct HyPortLibrary *portLibrary,
+			struct HyWin32SignalInfo *info, I_32 index,
+			const char **name, void **value);
+
+static void removeAsyncHandlers (HyPortLibrary * portLibrary);
+
+static void fillInWin32SignalInfo (struct HyPortLibrary *portLibrary,
+				   hysig_handler_fn handler,
+				   EXCEPTION_POINTERS * exceptionInfo,
+				   struct HyWin32SignalInfo *hyinfo);
+
+static U_32 infoForSignal (struct HyPortLibrary *portLibrary,
+			   struct HyWin32SignalInfo *info, I_32 index,
+			   const char **name, void **value);
+
+static U_32 infoForModule (struct HyPortLibrary *portLibrary,
+			   struct HyWin32SignalInfo *info, I_32 index,
+			   const char **name, void **value);
+
+static U_32 countInfoInCategory (struct HyPortLibrary *portLibrary,
+				 void *info, U_32 category);
+
+static BOOL WINAPI consoleCtrlHandler (DWORD dwCtrlType);
+
+int structuredExceptionHandler (struct HyPortLibrary *portLibrary,
+				hysig_handler_fn handler, void *handler_arg,
+				U_32 flags,
+				EXCEPTION_POINTERS * exceptionInfo);
+
+static U_32 infoForControl (struct HyPortLibrary *portLibrary,
+			    struct HyWin32SignalInfo *info, I_32 index,
+			    const char **name, void **value);
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_info
+U_32 VMCALL
+hysig_info (struct HyPortLibrary *portLibrary, void *info, U_32 category,
+	    I_32 index, const char **name, void **value)
+{
+  *name = "";
+
+  switch (category)
+    {
+    case HYPORT_SIG_SIGNAL:
+      return infoForSignal (portLibrary, info, index, name, value);
+    case HYPORT_SIG_GPR:
+      return infoForGPR (portLibrary, info, index, name, value);
+    case HYPORT_SIG_CONTROL:
+      return infoForControl (portLibrary, info, index, name, value);
+    case HYPORT_SIG_MODULE:
+      return infoForModule (portLibrary, info, index, name, value);
+    case HYPORT_SIG_FPR:
+    case HYPORT_SIG_OTHER:
+
+    default:
+      return HYPORT_SIG_VALUE_UNDEFINED;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_info_count
+U_32 VMCALL
+hysig_info_count (struct HyPortLibrary * portLibrary, void *info,
+		  U_32 category)
+{
+  return countInfoInCategory (portLibrary, info, category);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_protect
+I_32 VMCALL
+hysig_protect (struct HyPortLibrary * portLibrary, hysig_protected_fn fn,
+	       void *fn_arg, hysig_handler_fn handler, void *handler_arg,
+	       U_32 flags, UDATA * result)
+{
+  __try
+  {
+    *result = fn (portLibrary, fn_arg);
+  } __except (structuredExceptionHandler
+	      (portLibrary, handler, handler_arg, flags,
+	       GetExceptionInformation ()))
+  {
+    /* this code is only reachable if the handler returned HYPORT_SIG_EXCEPTION_RETURN */
+    *result = 0;
+    return HYPORT_SIG_EXCEPTION_OCCURRED;
+  }
+
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_set_async_signal_handler
+U_32 VMCALL
+hysig_set_async_signal_handler (struct HyPortLibrary * portLibrary,
+				hysig_handler_fn handler, void *handler_arg,
+				U_32 flags)
+{
+  U_32 rc = 0;
+  HyWin32AsyncHandlerRecord *cursor;
+  HyWin32AsyncHandlerRecord **previousLink;
+
+  hythread_monitor_enter (asyncMonitor);
+
+  /* wait until no signals are being reported */
+  while (asyncThreadCount > 0)
+    {
+      hythread_monitor_wait (asyncMonitor);
+    }
+
+  /* is this handler already registered? */
+  previousLink = &asyncHandlerList;
+  cursor = asyncHandlerList;
+  while (cursor)
+    {
+      if ((cursor->portLib == portLibrary) && (cursor->handler == handler)
+	  && (cursor->handler_arg == handler_arg))
+	{
+	  if (flags == 0)
+	    {
+	      *previousLink = cursor->next;
+	      portLibrary->mem_free_memory (portLibrary, cursor);
+
+	      /* if this is the last handler, unregister the Win32 handler function */
+	      if (asyncHandlerList == NULL)
+		{
+		  SetConsoleCtrlHandler (consoleCtrlHandler, FALSE);
+		}
+	    }
+	  else
+	    {
+	      cursor->flags = flags;
+	    }
+	  break;
+	}
+      previousLink = &cursor->next;
+      cursor = cursor->next;
+    }
+
+  if (cursor == NULL)
+    {
+      /* cursor will only be NULL if we failed to find it in the list */
+      if (flags != 0)
+	{
+	  HyWin32AsyncHandlerRecord *record =
+	    portLibrary->mem_allocate_memory (portLibrary, sizeof (*record));
+
+	  if (record == NULL)
+	    {
+	      rc = 1;
+	    }
+	  else
+	    {
+	      record->portLib = portLibrary;
+	      record->handler = handler;
+	      record->handler_arg = handler_arg;
+	      record->flags = flags;
+	      record->next = NULL;
+
+	      /* if this is the first handler, register the Win32 handler function */
+	      if (asyncHandlerList == NULL)
+		{
+		  SetConsoleCtrlHandler (consoleCtrlHandler, TRUE);
+		}
+
+	      /* add the new record to the end of the list */
+	      *previousLink = record;
+	    }
+	}
+    }
+
+  hythread_monitor_exit (asyncMonitor);
+
+  return rc;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_can_protect
+I_32 VMCALL
+hysig_can_protect (struct HyPortLibrary * portLibrary, U_32 flags)
+{
+  U_32 supportedFlags =
+    HYPORT_SIG_FLAG_MAY_RETURN | HYPORT_SIG_FLAG_MAY_CONTINUE_EXECUTION;
+
+  supportedFlags |=
+    HYPORT_SIG_FLAG_SIGALLSYNC | HYPORT_SIG_FLAG_SIGQUIT |
+    HYPORT_SIG_FLAG_SIGTERM;
+
+  if ((flags & supportedFlags) == flags)
+    {
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_shutdown
+/**
+ * Shutdown the signal handling component of the port library
+ */
+void VMCALL
+hysig_shutdown (struct HyPortLibrary *portLibrary)
+{
+  hythread_monitor_t globalMonitor = hythread_global_monitor ();
+
+  removeAsyncHandlers (portLibrary);
+
+  hythread_monitor_enter (globalMonitor);
+
+  if (--attachedPortLibraries == 0)
+    {
+      hythread_monitor_destroy (asyncMonitor);
+    }
+
+  hythread_monitor_exit (globalMonitor);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_startup
+/**
+ * Start up the signal handling component of the port library
+ */
+I_32 VMCALL
+hysig_startup (struct HyPortLibrary *portLibrary)
+{
+  hythread_monitor_t globalMonitor = hythread_global_monitor ();
+  I_32 result = 0;
+
+  hythread_monitor_enter (globalMonitor);
+
+  if (attachedPortLibraries++ == 0)
+    {
+      if (hythread_monitor_init_with_name
+	  (&asyncMonitor, 0, "portLibrary_hysig_async_monitor"))
+	{
+	  result = -1;
+	}
+    }
+
+  hythread_monitor_exit (globalMonitor);
+
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION structuredExceptionHandler
+int
+structuredExceptionHandler (struct HyPortLibrary *portLibrary,
+			    hysig_handler_fn handler, void *handler_arg,
+			    U_32 flags, EXCEPTION_POINTERS * exceptionInfo)
+{
+  U_32 result;
+  U_32 type;
+  struct HyWin32SignalInfo hyinfo;
+
+  if ((exceptionInfo->ExceptionRecord->
+       ExceptionCode & (ERROR_SEVERITY_ERROR | APPLICATION_ERROR_MASK)) !=
+      ERROR_SEVERITY_ERROR)
+    {
+      return EXCEPTION_CONTINUE_SEARCH;
+    }
+
+  type =
+    mapWin32ExceptionToPortlibType (exceptionInfo->ExceptionRecord->
+				    ExceptionCode);
+  if (0 == (type & flags))
+    {
+      return EXCEPTION_CONTINUE_SEARCH;
+    }
+
+  fillInWin32SignalInfo (portLibrary, handler, exceptionInfo, &hyinfo);
+
+  __try
+  {
+    result = handler (portLibrary, hyinfo.type, &hyinfo, handler_arg);
+  }
+  __except (EXCEPTION_EXECUTE_HANDLER)
+  {
+    /* if a recursive exception occurs, ignore it and pass control to the next handler */
+    return EXCEPTION_CONTINUE_SEARCH;
+  }
+
+  if (result == HYPORT_SIG_EXCEPTION_CONTINUE_SEARCH)
+    {
+      return EXCEPTION_CONTINUE_SEARCH;
+    }
+  else if (result == HYPORT_SIG_EXCEPTION_CONTINUE_EXECUTION)
+    {
+      return EXCEPTION_CONTINUE_EXECUTION;
+    }
+  else				/* if (result == HYPORT_SIG_EXCEPTION_RETURN) */
+    {
+      return EXCEPTION_EXECUTE_HANDLER;
+    }
+
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION mapWin32ExceptionToPortlibType
+static U_32
+mapWin32ExceptionToPortlibType (U_32 exceptionCode)
+{
+  switch (exceptionCode)
+    {
+
+    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+      return HYPORT_SIG_FLAG_SIGFPE_DIV_BY_ZERO;
+
+    case EXCEPTION_INT_DIVIDE_BY_ZERO:
+      return HYPORT_SIG_FLAG_SIGFPE_INT_DIV_BY_ZERO;
+
+    case EXCEPTION_INT_OVERFLOW:
+      return HYPORT_SIG_FLAG_SIGFPE_INT_OVERFLOW;
+
+    case EXCEPTION_FLT_OVERFLOW:
+    case EXCEPTION_FLT_UNDERFLOW:
+    case EXCEPTION_FLT_INVALID_OPERATION:
+    case EXCEPTION_FLT_INEXACT_RESULT:
+    case EXCEPTION_FLT_DENORMAL_OPERAND:
+    case EXCEPTION_FLT_STACK_CHECK:
+      return HYPORT_SIG_FLAG_SIGFPE;
+
+    case EXCEPTION_PRIV_INSTRUCTION:
+    case EXCEPTION_ILLEGAL_INSTRUCTION:
+      return HYPORT_SIG_FLAG_SIGILL;
+
+    case EXCEPTION_ACCESS_VIOLATION:
+      return HYPORT_SIG_FLAG_SIGSEGV;
+
+    case EXCEPTION_IN_PAGE_ERROR:
+    case EXCEPTION_DATATYPE_MISALIGNMENT:
+      return HYPORT_SIG_FLAG_SIGBUS;
+
+    default:
+      return HYPORT_SIG_FLAG_SIGTRAP;
+
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION fillInWin32SignalInfo
+static void
+fillInWin32SignalInfo (struct HyPortLibrary *portLibrary,
+		       hysig_handler_fn handler,
+		       EXCEPTION_POINTERS * exceptionInfo,
+		       struct HyWin32SignalInfo *hyinfo)
+{
+  memset (hyinfo, 0, sizeof (*hyinfo));
+
+  hyinfo->type =
+    mapWin32ExceptionToPortlibType (exceptionInfo->ExceptionRecord->
+				    ExceptionCode);
+  hyinfo->handlerAddress = (void *) handler;
+  hyinfo->handlerAddress2 = (void *) structuredExceptionHandler;
+  hyinfo->ExceptionRecord = exceptionInfo->ExceptionRecord;
+  hyinfo->ContextRecord = exceptionInfo->ContextRecord;
+
+  /* module info is filled on demand */
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION infoForSignal
+static U_32
+infoForSignal (struct HyPortLibrary *portLibrary,
+	       struct HyWin32SignalInfo *info, I_32 index, const char **name,
+	       void **value)
+{
+  *name = "";
+
+  switch (index)
+    {
+
+    case HYPORT_SIG_SIGNAL_TYPE:
+    case 0:
+      *name = "HyGeneric_Signal_Number";
+      *value = &info->type;
+      return HYPORT_SIG_VALUE_32;
+
+    case HYPORT_SIG_SIGNAL_PLATFORM_SIGNAL_TYPE:
+    case 1:
+      *name = "ExceptionCode";
+      *value = &info->ExceptionRecord->ExceptionCode;
+      return HYPORT_SIG_VALUE_32;
+
+    case HYPORT_SIG_SIGNAL_ADDRESS:
+    case 2:
+      *name = "ExceptionAddress";
+      *value = &info->ExceptionRecord->ExceptionAddress;
+      return HYPORT_SIG_VALUE_ADDRESS;
+
+    case 3:
+      *name = "ContextFlags";
+      *value = &info->ContextRecord->ContextFlags;
+      return HYPORT_SIG_VALUE_32;
+
+    case HYPORT_SIG_SIGNAL_HANDLER:
+    case 4:
+      *name = "Handler1";
+      *value = &info->handlerAddress;
+      return HYPORT_SIG_VALUE_ADDRESS;
+
+    case 5:
+      *name = "Handler2";
+      *value = &info->handlerAddress2;
+      return HYPORT_SIG_VALUE_ADDRESS;
+
+    case HYPORT_SIG_SIGNAL_INACCESSIBLE_ADDRESS:
+    case 6:
+      if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
+	{
+	  *name = "InaccessibleAddress";
+	  *value = &info->ExceptionRecord->ExceptionInformation[1];
+	  return HYPORT_SIG_VALUE_ADDRESS;
+	}
+      else
+	{
+	  return HYPORT_SIG_VALUE_UNDEFINED;
+	}
+
+    default:
+      return HYPORT_SIG_VALUE_UNDEFINED;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION infoForGPR
+static U_32
+infoForGPR (struct HyPortLibrary *portLibrary, struct HyWin32SignalInfo *info,
+	    I_32 index, const char **name, void **value)
+{
+  *name = "";
+
+  if (info->ContextRecord->ContextFlags & CONTEXT_INTEGER)
+    {
+      switch (index)
+	{
+	case HYPORT_SIG_GPR_X86_EDI:
+	case 0:
+	  *name = "EDI";
+	  *value = &info->ContextRecord->Edi;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_GPR_X86_ESI:
+	case 1:
+	  *name = "ESI";
+	  *value = &info->ContextRecord->Esi;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_GPR_X86_EAX:
+	case 2:
+	  *name = "EAX";
+	  *value = &info->ContextRecord->Eax;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_GPR_X86_EBX:
+	case 3:
+	  *name = "EBX";
+	  *value = &info->ContextRecord->Ebx;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_GPR_X86_ECX:
+	case 4:
+	  *name = "ECX";
+	  *value = &info->ContextRecord->Ecx;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_GPR_X86_EDX:
+	case 5:
+	  *name = "EDX";
+	  *value = &info->ContextRecord->Edx;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	default:
+	  return HYPORT_SIG_VALUE_UNDEFINED;
+	}
+    }
+
+  return HYPORT_SIG_VALUE_UNDEFINED;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION infoForControl
+static U_32
+infoForControl (struct HyPortLibrary *portLibrary,
+		struct HyWin32SignalInfo *info, I_32 index, const char **name,
+		void **value)
+{
+  *name = "";
+
+  if (info->ContextRecord->ContextFlags & CONTEXT_CONTROL)
+    {
+      switch (index)
+	{
+	case HYPORT_SIG_CONTROL_PC:
+	case 0:
+	  *name = "EIP";
+	  *value = &info->ContextRecord->Eip;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_CONTROL_SP:
+	case 1:
+	  *name = "ESP";
+	  *value = &info->ContextRecord->Esp;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	case HYPORT_SIG_CONTROL_BP:
+	case 2:
+	  *name = "EBP";
+	  *value = &info->ContextRecord->Ebp;
+	  return HYPORT_SIG_VALUE_ADDRESS;
+
+	default:
+	  return HYPORT_SIG_VALUE_UNDEFINED;
+	}
+    }
+  return HYPORT_SIG_VALUE_UNDEFINED;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION infoForModule
+static U_32
+infoForModule (struct HyPortLibrary *portLibrary,
+	       struct HyWin32SignalInfo *info, I_32 index, const char **name,
+	       void **value)
+{
+  if (info->moduleBaseAddress == NULL)
+    {
+      MEMORY_BASIC_INFORMATION mbi;
+
+      if (VirtualQuery
+	  ((LPBYTE) info->ExceptionRecord->ExceptionAddress, &mbi,
+	   sizeof (mbi)) == sizeof (mbi))
+	{
+	  if (MEM_FREE == mbi.State)
+	    {
+	      /* from Advanced Windows (Richter) */
+	      mbi.AllocationBase = mbi.BaseAddress;
+	    }
+
+	  GetModuleFileName ((HINSTANCE) mbi.AllocationBase, info->moduleName,
+			     sizeof (info->moduleName));
+	  info->moduleBaseAddress = mbi.AllocationBase;
+	  info->offsetInDLL =
+	    (UDATA) info->ExceptionRecord->ExceptionAddress -
+	    (UDATA) mbi.AllocationBase;
+	}
+    }
+
+  *name = "";
+
+  switch (index)
+    {
+    case HYPORT_SIG_MODULE_NAME:
+    case 0:
+      *name = "Module";
+      *value = &info->moduleName;
+      return HYPORT_SIG_VALUE_STRING;
+    case 1:
+      *name = "Module_base_address";
+      *value = &info->moduleBaseAddress;
+      return HYPORT_SIG_VALUE_ADDRESS;
+    case 2:
+      *name = "Offset_in_DLL";
+      *value = &info->offsetInDLL;
+      return HYPORT_SIG_VALUE_32;
+    default:
+      return HYPORT_SIG_VALUE_UNDEFINED;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION countInfoInCategory
+static U_32
+countInfoInCategory (struct HyPortLibrary *portLibrary, void *info,
+		     U_32 category)
+{
+  void *value;
+  const char *name;
+  U_32 count = 0;
+
+  while (portLibrary->
+	 sig_info (portLibrary, info, category, count, &name,
+		   &value) != HYPORT_SIG_VALUE_UNDEFINED)
+    {
+      count++;
+    }
+
+  return count;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION consoleCtrlHandler
+static BOOL WINAPI
+consoleCtrlHandler (DWORD dwCtrlType)
+{
+  U_32 flags;
+  BOOL result = FALSE;
+
+  switch (dwCtrlType)
+    {
+    case CTRL_BREAK_EVENT:
+      flags = HYPORT_SIG_FLAG_SIGQUIT;
+      break;
+    case CTRL_C_EVENT:
+      flags = HYPORT_SIG_FLAG_SIGTERM;
+      break;
+    default:
+      return result;
+    }
+
+  if (0 == hythread_attach (NULL))
+    {
+      HyWin32AsyncHandlerRecord *cursor;
+      U_32 handlerCount = 0;
+
+      /* incrementing the asyncThreadCount will prevent the list from being modified while we use it */
+      hythread_monitor_enter (asyncMonitor);
+      asyncThreadCount++;
+      hythread_monitor_exit (asyncMonitor);
+
+      cursor = asyncHandlerList;
+      while (cursor)
+	{
+	  if (cursor->flags & flags)
+	    {
+	      cursor->handler (cursor->portLib, flags, NULL,
+			       cursor->handler_arg);
+	      result = TRUE;
+	    }
+	  cursor = cursor->next;
+	}
+
+      hythread_monitor_enter (asyncMonitor);
+      if (--asyncThreadCount == 0)
+	{
+	  hythread_monitor_notify_all (asyncMonitor);
+	}
+      hythread_monitor_exit (asyncMonitor);
+
+      /* TODO: possible timing hole. The thread library could be unloaded by the time we
+       * reach this line. We can't use hythread_exit(), as that kills the async reporting thread
+       */
+      hythread_detach (NULL);
+    }
+
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION removeAsyncHandlers
+static void
+removeAsyncHandlers (HyPortLibrary * portLibrary)
+{
+  /* clean up the list of async handlers */
+  HyWin32AsyncHandlerRecord *cursor;
+  HyWin32AsyncHandlerRecord **previousLink;
+
+  hythread_monitor_enter (asyncMonitor);
+
+  /* wait until no signals are being reported */
+  while (asyncThreadCount > 0)
+    {
+      hythread_monitor_wait (asyncMonitor);
+    }
+
+  previousLink = &asyncHandlerList;
+  cursor = asyncHandlerList;
+  while (cursor)
+    {
+      if (cursor->portLib == portLibrary)
+	{
+	  *previousLink = cursor->next;
+	  portLibrary->mem_free_memory (portLibrary, cursor);
+	  cursor = *previousLink;
+	}
+      else
+	{
+	  previousLink = &cursor->next;
+	  cursor = cursor->next;
+	}
+    }
+
+  if (asyncHandlerList == NULL)
+    {
+      SetConsoleCtrlHandler (consoleCtrlHandler, FALSE);
+    }
+
+  hythread_monitor_exit (asyncMonitor);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_set_options
+/**
+ * none of the current options are supported by windows IA32
+ */
+I_32 VMCALL
+hysig_set_options (struct HyPortLibrary *portLibrary, U_32 options)
+{
+
+  if (options == 0)
+    {
+      signalOptions = options;
+      return 0;
+    }
+  else
+    {
+      return -1;
+    }
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysig_get_options
+/* these options should always be 0 */
+U_32 VMCALL
+hysig_get_options (struct HyPortLibrary * portLibrary)
+{
+  return signalOptions;
+}
+
+#undef CDEV_CURRENT_FUNCTION

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysignal.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,33 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(hysignal_h)
+#define hysignal_h
+
+#include "hycomp.h"
+
+typedef struct HyWin32SignalInfo
+{
+  U_32 type;
+  void *handlerAddress;
+  void *handlerAddress2;
+  struct _EXCEPTION_RECORD *ExceptionRecord;
+  struct _CONTEXT *ContextRecord;
+  void *moduleBaseAddress;
+  U_32 offsetInDLL;
+  char moduleName[_MAX_PATH];
+} HyWin32SignalInfo;
+
+#endif /* hysignal_h */

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysl.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysl.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysl.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/port/hysl.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,337 @@
+/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define CDEV_CURRENT_FUNCTION _comment_
+/**
+ * @file
+ * @ingroup Port
+ * @brief shared library
+ */
+#undef CDEV_CURRENT_FUNCTION
+
+#include <windows.h>
+#include "hyport.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include "hylib.h"
+#include "portnls.h"
+
+#if !defined(HINSTANCE_ERROR)
+#define	HINSTANCE_ERROR	32
+#endif
+
+#define CDEV_CURRENT_FUNCTION _prototypes_private
+UDATA VMCALL EsSharedLibraryLookupName (UDATA descriptor, char *name,
+					UDATA * func);
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION EsSharedLibraryLookupName
+UDATA VMCALL
+EsSharedLibraryLookupName (UDATA descriptor, char *name, UDATA * func)
+{
+  UDATA lpfnFunction;
+
+  if (descriptor < HINSTANCE_ERROR)
+    {
+      return 3;
+    }
+  lpfnFunction =
+    (UDATA) GetProcAddress ((HINSTANCE) descriptor, (LPCSTR) name);
+  if (lpfnFunction == (UDATA) NULL)
+    {
+      return 4;
+    }
+  *func = lpfnFunction;
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysl_open_shared_library
+/** 
+ * Opens a shared library.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] name path Null-terminated string containing the shared library.
+ * @param[out] descriptor Pointer to memory which is filled in with shared-library handle on success.
+ * @param[in] decorate Boolean value indicates whether name should be decorated
+ *            if it contains path information and cannot be found.
+ *
+ * @return 0 on success, any other value on failure.
+ *
+ * @note contents of descriptor are undefined on failure.
+ */
+UDATA VMCALL
+hysl_open_shared_library (struct HyPortLibrary * portLibrary, char *name,
+			  UDATA * descriptor, BOOLEAN decorate)
+{
+  HINSTANCE dllHandle;
+  UINT prevMode;
+  DWORD error;
+  UDATA notFound;
+  const char *errorMessage;
+  char errBuf[512];
+  char mangledName[1024];
+  char *openName = name;
+
+  if (decorate)
+    {
+      portLibrary->str_printf (portLibrary, mangledName, 1024, "%s.dll",
+			       name);
+      openName = mangledName;
+    }				/* TODO make windows not try to append .dll if we do not want it to */
+
+  prevMode = SetErrorMode (SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
+
+  /* LoadLibrary will try appending .DLL if necessary */
+  dllHandle = LoadLibrary ((LPCSTR) openName);
+  if (dllHandle >= (HINSTANCE) HINSTANCE_ERROR)
+    {
+      *descriptor = (UDATA) dllHandle;
+      SetErrorMode (prevMode);
+      return 0;
+    }
+
+  error = GetLastError ();
+
+  notFound = (error == ERROR_MOD_NOT_FOUND || error == ERROR_DLL_NOT_FOUND);
+  if (notFound)
+    {
+      /* try to report a better error message.  Check if the library can be found at all. */
+      dllHandle =
+	LoadLibraryEx ((LPCSTR) openName, NULL, DONT_RESOLVE_DLL_REFERENCES);
+      if (dllHandle)
+	{
+	  if (sizeof (errBuf))
+	    {
+	      errorMessage = portLibrary->nls_lookup_message (portLibrary,
+							      HYNLS_ERROR |
+							      HYNLS_DO_NOT_APPEND_NEWLINE,
+							      HYNLS_PORT_SL_UNABLE_TO_RESOLVE_REFERENCES,
+							      NULL);
+	      strncpy (errBuf, errorMessage, sizeof (errBuf));
+	      errBuf[sizeof (errBuf) - 1] = '\0';
+	    }
+	  FreeLibrary (dllHandle);
+	  SetErrorMode (prevMode);
+	  return portLibrary->error_set_last_error_with_message (portLibrary,
+								 HYPORT_SL_INVALID,
+								 errBuf);
+	}
+    }
+
+  if (sizeof (errBuf))
+    {
+      LPWSTR message = NULL;
+      int nameSize = strlen (name);
+      LPWSTR filename =
+	(LPWSTR) portLibrary->mem_allocate_memory (portLibrary,
+						   nameSize * 2 + 2);
+
+      if (filename == NULL)
+	{
+	  errorMessage = portLibrary->nls_lookup_message (portLibrary,
+							  HYNLS_ERROR |
+							  HYNLS_DO_NOT_APPEND_NEWLINE,
+							  HYNLS_PORT_SL_INTERNAL_ERROR,
+							  NULL);
+	  portLibrary->str_printf (portLibrary, errBuf, sizeof (errBuf),
+				   errorMessage, error);
+	  errBuf[sizeof (errBuf) - 1] = '\0';
+	  SetErrorMode (prevMode);
+	  return portLibrary->error_set_last_error_with_message (portLibrary,
+								 notFound ?
+								 HYPORT_SL_NOT_FOUND
+								 :
+								 HYPORT_SL_INVALID,
+								 errBuf);
+	}
+
+      MultiByteToWideChar (CP_ACP, 0, (LPCTSTR) name, -1, filename,
+			   nameSize * 2 + 2);
+      filename[nameSize] = '\0';
+
+      FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),	/* Default language */
+		      (LPWSTR) & message, 0, (va_list *) & filename);
+
+      portLibrary->mem_free_memory (portLibrary, filename);
+
+      if (message)
+	{
+	  WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR) message, -1, errBuf,
+			       sizeof (errBuf) - 1, NULL, NULL);
+	  LocalFree (message);
+	}
+      else
+	{
+	  errorMessage = portLibrary->nls_lookup_message (portLibrary,
+							  HYNLS_ERROR |
+							  HYNLS_DO_NOT_APPEND_NEWLINE,
+							  HYNLS_PORT_SL_INTERNAL_ERROR,
+							  NULL);
+	  portLibrary->str_printf (portLibrary, errBuf, sizeof (errBuf),
+				   errorMessage, error);
+	}
+      errBuf[sizeof (errBuf) - 1] = '\0';
+    }
+
+  SetErrorMode (prevMode);
+
+  return portLibrary->error_set_last_error_with_message (portLibrary,
+							 notFound ?
+							 HYPORT_SL_NOT_FOUND :
+							 HYPORT_SL_INVALID,
+							 errBuf);
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysl_close_shared_library
+/**
+ * Close a shared library.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] descriptor Shared library handle to close.
+ *
+ * @return 0 on success, any other value on failure.
+ */
+UDATA VMCALL
+hysl_close_shared_library (struct HyPortLibrary * portLibrary,
+			   UDATA descriptor)
+{
+  if (descriptor < HINSTANCE_ERROR)
+    {
+      return 2;
+    }
+  FreeLibrary ((HINSTANCE) descriptor);
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysl_lookup_name
+/**
+ * Search for a function named 'name' taking argCount in the shared library 'descriptor'.
+ *
+ * @param[in] portLibrary The port library.
+ * @param[in] descriptor Shared library to search.
+ * @param[in] name Function to look up.
+ * @param[out] func Pointer to the function.
+ * @param[in] argSignature Argument signature.
+ *
+ * @return 0 on success, any other value on failure.
+ *
+ * argSignature is a C (ie: NUL-terminated) string with the following possible values for each character:
+ *
+ *		V	- void
+ *		Z	- boolean
+ *		B	- byte
+ *		C	- char (16 bits)
+ *		I	- integer (32 bits)
+ *		J	- long (64 bits)
+ *		F	- float (32 bits) 
+ *		D	- double (64 bits) 
+ *		L	- object / pointer (32 or 64, depending on platform)
+ *		P	- pointer-width platform data. (in this context an IDATA)
+ *
+ * Lower case signature characters imply unsigned value.
+ * Upper case signature characters imply signed values.
+ * If it doesn't make sense to be signed/unsigned (eg: V, L, F, D Z) the character is upper case.
+ * 
+ * argList[0] is the return type from the function.
+ * The argument list is as it appears in english: list is left (1) to right (argCount)
+ *
+ * @note contents of func are undefined on failure.
+ */
+UDATA VMCALL
+hysl_lookup_name (struct HyPortLibrary * portLibrary, UDATA descriptor,
+		  char *name, UDATA * func, const char *argSignature)
+{
+  char *mangledName;
+  UDATA result;
+
+  result = EsSharedLibraryLookupName (descriptor, name, func);
+  if (result != 0)
+    {
+      int i, len, pad = 0;
+
+      /* + 7 comes from: 256 parameters * 8 bytes each = 2048 bytes -> 4 digits + @ symbol + leading '_' + NULL */
+      size_t length = sizeof (char) * (strlen (name) + 7);
+      if (!(mangledName = (char *) alloca (length)))
+	{
+	  return 1;
+	}
+
+      len = strlen (argSignature);
+
+      for (i = 1; i < len; i++)
+	{
+	  if (argSignature[i] == 'J' || argSignature[i] == 'D')
+	    {
+	      pad++;
+	    }
+	}
+
+      portLibrary->str_printf (portLibrary, mangledName, length, "_%s@%d",
+			       name, (len + pad - 1) * 4);
+      result = EsSharedLibraryLookupName (descriptor, mangledName, func);
+    }
+  return result;
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysl_shutdown
+/**
+ * PortLibrary shutdown.
+ *
+ * This function is called during shutdown of the portLibrary.  Any resources that were created by @ref hysl_startup
+ * should be destroyed here.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @note Most implementations will be empty.
+ */
+void VMCALL
+hysl_shutdown (struct HyPortLibrary *portLibrary)
+{
+  /* empty */
+}
+
+#undef CDEV_CURRENT_FUNCTION
+
+#define CDEV_CURRENT_FUNCTION hysl_startup
+/**
+ * PortLibrary startup.
+ *
+ * This function is called during startup of the portLibrary.  Any resources that are required for
+ * the shared library operations may be created here.  All resources created here should be destroyed
+ * in @ref hysl_shutdown.
+ *
+ * @param[in] portLibrary The port library.
+ *
+ * @return 0 on success, negative error code on failure.  Error code values returned are
+ * \arg HYPORT_ERROR_STARTUP_SL
+ *
+ * @note Most implementations will simply return success.
+ */
+I_32 VMCALL
+hysl_startup (struct HyPortLibrary *portLibrary)
+{
+  return 0;
+}
+
+#undef CDEV_CURRENT_FUNCTION



Mime
View raw message