]> granicus.if.org Git - imagemagick/commitdiff
Added support for distributed pixel cache to the Windows distribution.
authordirk <dirk@git.imagemagick.org>
Mon, 22 Dec 2014 01:38:36 +0000 (01:38 +0000)
committerdirk <dirk@git.imagemagick.org>
Mon, 22 Dec 2014 01:38:36 +0000 (01:38 +0000)
MagickCore/distribute-cache.c
MagickCore/magick.c
MagickCore/nt-base-private.h
MagickCore/nt-base.c
MagickCore/studio.h

index ada74191e3dab8e38945fec297daa1b5418e29aa..e1a2022a28a1540e3ba435da1b1ac01c114af411 100644 (file)
 #include "MagickCore/string-private.h"
 #include "MagickCore/version.h"
 #include "MagickCore/version-private.h"
+#undef MAGICKCORE_HAVE_DISTRIBUTE_CACHE
 #if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_THREAD_SUPPORT)
 #include <netinet/in.h>
 #include <netdb.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#define CHAR_TYPE_CAST
+#define CLOSE_SOCKET(socket) (void) close(socket)
+#define HANDLER_RETURN_TYPE void *
+#define HANDLER_RETURN_VALUE (void *) NULL
+#define SOCKET_TYPE int
+#define MAGICKCORE_HAVE_DISTRIBUTE_CACHE
+#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
+#define CHAR_TYPE_CAST (char *)
+#define CLOSE_SOCKET(socket) (void) closesocket(socket)
+#define HANDLER_RETURN_TYPE DWORD WINAPI
+#define HANDLER_RETURN_VALUE 0
+#define SOCKET_TYPE SOCKET
+#define MAGICKCORE_HAVE_DISTRIBUTE_CACHE
 #else
 #undef send
 #undef recv
@@ -136,7 +150,7 @@ static inline MagickOffsetType dpc_read(int file,const MagickSizeType length,
   ssize_t
     count;
 
-#if !defined(MAGICKCORE_HAVE_SOCKET) || !defined(MAGICKCORE_THREAD_SUPPORT)
+#if !defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
   magick_unreferenced(file);
   magick_unreferenced(message);
 #endif
@@ -144,8 +158,8 @@ static inline MagickOffsetType dpc_read(int file,const MagickSizeType length,
   count=0;
   for (i=0; i < (MagickOffsetType) length; i+=count)
   {
-    count=recv(file,message+i,(size_t) MagickMin(length-i,(MagickSizeType)
-      SSIZE_MAX),0);
+    count=recv(file,CHAR_TYPE_CAST message+i,(size_t) MagickMin(length-i,
+      (MagickSizeType) SSIZE_MAX),0);
     if (count <= 0)
       {
         count=0;
@@ -159,7 +173,7 @@ static inline MagickOffsetType dpc_read(int file,const MagickSizeType length,
 static int ConnectPixelCacheServer(const char *hostname,const int port,
   size_t *session_key,ExceptionInfo *exception)
 {
-#if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_THREAD_SUPPORT)
+#if defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
   char
     service[MaxTextExtent];
 
@@ -167,9 +181,11 @@ static int ConnectPixelCacheServer(const char *hostname,const int port,
     *shared_secret;
 
   int
-    client_socket,
     status;
 
+  SOCKET_TYPE
+    client_socket;
+
   ssize_t
     count;
 
@@ -191,6 +207,9 @@ static int ConnectPixelCacheServer(const char *hostname,const int port,
         "DistributedPixelCache","'%s'","shared secret expected");
       return(-1);
     }
+#if defined(MAGICKCORE_WINDOWS_SUPPORT)
+  NTInitializeWinsock(MagickTrue);
+#endif
   (void) ResetMagickMemory(&hint,0,sizeof(hint));
   hint.ai_family=AF_INET;
   hint.ai_socktype=SOCK_STREAM;
@@ -214,12 +233,11 @@ static int ConnectPixelCacheServer(const char *hostname,const int port,
   status=connect(client_socket,result->ai_addr,result->ai_addrlen);
   if (status == -1)
     {
-      (void) close(client_socket);
       (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
         "DistributedPixelCache","'%s'",hostname);
       return(-1);
     }
-  count=recv(client_socket,secret,MaxTextExtent,0);
+  count=recv(client_socket,CHAR_TYPE_CAST secret,MaxTextExtent,0);
   if (count != -1)
     {
       StringInfo
@@ -232,8 +250,8 @@ static int ConnectPixelCacheServer(const char *hostname,const int port,
     }
   if (*session_key == 0)
     {
-      close(client_socket);
-      client_socket=(-1);
+      CLOSE_SOCKET(client_socket);
+      client_socket=(SOCKET_TYPE) (-1);
     }
   return(client_socket);
 #else
@@ -365,7 +383,7 @@ MagickPrivate DistributeCacheInfo *DestroyDistributeCacheInfo(
   assert(server_info != (DistributeCacheInfo *) NULL);
   assert(server_info->signature == MagickSignature);
   if (server_info->file > 0)
-    (void) close(server_info->file);
+    CLOSE_SOCKET(server_info->file);
   server_info->signature=(~MagickSignature);
   server_info=(DistributeCacheInfo *) RelinquishMagickMemory(server_info);
   return(server_info);
@@ -415,7 +433,7 @@ static inline MagickOffsetType dpc_send(int file,const MagickSizeType length,
   register MagickOffsetType
     i;
 
-#if !defined(MAGICKCORE_HAVE_SOCKET) || !defined(MAGICKCORE_THREAD_SUPPORT)
+#if !defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
   magick_unreferenced(file);
   magick_unreferenced(message);
 #endif
@@ -426,7 +444,7 @@ static inline MagickOffsetType dpc_send(int file,const MagickSizeType length,
   count=0;
   for (i=0; i < (MagickOffsetType) length; i+=count)
   {
-    count=(MagickOffsetType) send(file,message+i,(size_t) MagickMin(length-i,
+    count=(MagickOffsetType) send(file,CHAR_TYPE_CAST message+i,(size_t) MagickMin(length-i,
       (MagickSizeType) SSIZE_MAX),MSG_NOSIGNAL);
     if (count <= 0)
       {
@@ -740,7 +758,7 @@ static MagickBooleanType WriteDistributeCachePixels(SplayTreeInfo *registry,
   return(SyncAuthenticPixels(image,exception));
 }
 
-static void *DistributePixelCacheClient(void *socket)
+static HANDLER_RETURN_TYPE DistributePixelCacheClient(void *socket)
 {
   const char
     *shared_secret;
@@ -748,9 +766,6 @@ static void *DistributePixelCacheClient(void *socket)
   ExceptionInfo
     *exception;
 
-  int
-    client_socket;
-
   MagickBooleanType
     status;
 
@@ -767,6 +782,9 @@ static void *DistributePixelCacheClient(void *socket)
     key,
     session_key;
 
+  SOCKET_TYPE
+    client_socket;
+
   SplayTreeInfo
     *registry;
 
@@ -794,7 +812,7 @@ static void *DistributePixelCacheClient(void *socket)
   exception=AcquireExceptionInfo();
   registry=NewSplayTree((int (*)(const void *,const void *)) NULL,
     (void *(*)(void *)) NULL,RelinquishImageRegistry);
-  client_socket=(*(int *) socket);
+  client_socket=(*(SOCKET_TYPE *) socket);
   count=dpc_send(client_socket,DPCSessionKeyLength,GetStringInfoDatum(secret));
   secret=DestroyStringInfo(secret);
   for ( ; ; )
@@ -853,32 +871,41 @@ static void *DistributePixelCacheClient(void *socket)
       break;
   }
   count=dpc_send(client_socket,sizeof(status),(unsigned char *) &status);
-  (void) close(client_socket);
+  CLOSE_SOCKET(client_socket);
   exception=DestroyExceptionInfo(exception);
   registry=DestroySplayTree(registry);
-  return((void *) NULL);
+  return(HANDLER_RETURN_VALUE);
 }
 
 MagickExport void DistributePixelCacheServer(const int port,
   ExceptionInfo *exception)
 {
-#if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_THREAD_SUPPORT)
+#if defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
   char
     service[MaxTextExtent];
 
   int
-    server_socket,
     status;
 
+#if defined(MAGICKCORE_THREAD_SUPPORT)
   pthread_attr_t
     attributes;
 
   pthread_t
     threads;
+#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
+  DWORD
+    threadID;
+#else
+  Not implemented!
+#endif
 
   register struct addrinfo
     *p;
 
+  SOCKET_TYPE
+    server_socket;
+
   struct addrinfo
     hint,
     *result;
@@ -891,6 +918,9 @@ MagickExport void DistributePixelCacheServer(const int port,
   */
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
+#if defined(MAGICKCORE_WINDOWS_SUPPORT)
+  NTInitializeWinsock(MagickFalse);
+#endif
   (void) ResetMagickMemory(&hint,0,sizeof(hint));
   hint.ai_family=AF_INET;
   hint.ai_socktype=SOCK_STREAM;
@@ -899,7 +929,7 @@ MagickExport void DistributePixelCacheServer(const int port,
   status=getaddrinfo((const char *) NULL,service,&hint,&result);
   if (status != 0)
     ThrowFatalException(CacheFatalError,"UnableToListen");
-  server_socket=0;
+  server_socket=(SOCKET_TYPE) 0;
   for (p=result; p != (struct addrinfo *) NULL; p=p->ai_next)
   {
     int
@@ -909,17 +939,17 @@ MagickExport void DistributePixelCacheServer(const int port,
     if (server_socket == -1)
       continue;
     one=1;
-    status=setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&one,(socklen_t)
-      sizeof(one));
+    status=setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,
+      CHAR_TYPE_CAST &one,(socklen_t) sizeof(one));
     if (status == -1)
       {
-        (void) close(server_socket);
+        CLOSE_SOCKET(server_socket);
         continue;
       }
     status=bind(server_socket,p->ai_addr,p->ai_addrlen);
     if (status == -1)
       {
-        (void) close(server_socket);
+        CLOSE_SOCKET(server_socket);
         continue;
       }
     break;
@@ -930,10 +960,12 @@ MagickExport void DistributePixelCacheServer(const int port,
   status=listen(server_socket,DPCPendingConnections);
   if (status != 0)
     ThrowFatalException(CacheFatalError,"UnableToListen");
+#if defined(MAGICKCORE_THREAD_SUPPORT)
   pthread_attr_init(&attributes);
+#endif
   for ( ; ; )
   {
-    int
+    SOCKET_TYPE
       client_socket;
 
     socklen_t
@@ -943,14 +975,23 @@ MagickExport void DistributePixelCacheServer(const int port,
     client_socket=accept(server_socket,(struct sockaddr *) &address,&length);
     if (client_socket == -1)
       ThrowFatalException(CacheFatalError,"UnableToEstablishConnection");
+#if defined(MAGICKCORE_THREAD_SUPPORT)
     status=pthread_create(&threads,&attributes,DistributePixelCacheClient,
       (void *) &client_socket);
     if (status == -1)
       ThrowFatalException(CacheFatalError,"UnableToCreateClientThread");
+#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
+    if (CreateThread(0,0,DistributePixelCacheClient,(void*) &client_socket,0,
+        &threadID) == (HANDLE) NULL)
+      ThrowFatalException(CacheFatalError,"UnableToCreateClientThread");
+#else
+    Not implemented!
+#endif
   }
-  (void) close(server_socket);
 #else
-  ThrowFatalException(MissingDelegateError,"distributed pixel cache");
+  magick_unreferenced(port);
+  magick_unreferenced(exception);
+  ThrowFatalException(MissingDelegateError,"DelegateLibrarySupportNotBuiltIn");
 #endif
 }
 \f
index 23bb336c3964eab53ebad49407ecf59186bfa5dc..718d27bcf6b25bc84a4d7e8c05d19281c13cda7a 100644 (file)
@@ -1382,7 +1382,7 @@ MagickExport void MagickCoreTerminus(void)
   TypeComponentTerminus();
   ColorComponentTerminus();
 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
-  NTGhostscriptUnLoadDLL();
+  NTWindowsTerminus();
 #endif
   MagicComponentTerminus();
   DelegateComponentTerminus();
index cb3b32ae119646d669a2f68dc8783cec8652cc7c..bb4761471dd46abd05c5d463d90cc250af534d02 100644 (file)
@@ -152,11 +152,13 @@ extern MagickPrivate unsigned char
   *NTResourceToBlob(const char *);
 
 extern MagickPrivate void
-  NTWindowsGenesis(void),
   *NTGetLibrarySymbol(void *,const char *),
+  NTInitializeWinsock(MagickBooleanType),
   *NTMapMemory(char *,size_t,int,int,int,MagickOffsetType),
   *NTOpenLibrary(const char *),
-  NTSeekDirectory(DIR *,ssize_t);
+  NTSeekDirectory(DIR *,ssize_t),
+  NTWindowsGenesis(void),
+  NTWindowsTerminus(void);
 
 #endif /* !XS_VERSION */
 
index fadd42fd28eee9bc5f2b2852b0a669b2040121ca..c4d96969c3aacd46f2f428ff655d3a6857bd49be 100644 (file)
@@ -86,7 +86,11 @@ static void
   *ghost_handle = (void *) NULL;
 
 static SemaphoreInfo
-  *ghost_semaphore = (SemaphoreInfo *) NULL;
+  *ghost_semaphore = (SemaphoreInfo *) NULL,
+  *winsock_semaphore = (SemaphoreInfo *) NULL;
+
+static WSADATA
+  *wsaData = (WSADATA*) NULL;
 \f
 struct
 {
@@ -1472,6 +1476,42 @@ MagickPrivate int NTInitializeLibrary(void)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   N T I n i t i a l i z e W i n s o c k                                     %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTInitializeWinsock() initializes Winsock.
+%
+%  The format of the NTInitializeWinsock method is:
+%
+%      void NTInitializeWinsock(void)
+%
+*/
+MagickPrivate void NTInitializeWinsock(MagickBooleanType use_lock)
+{
+  if (use_lock)
+    {
+      if (winsock_semaphore == (SemaphoreInfo *) NULL)
+        ActivateSemaphoreInfo(&winsock_semaphore);
+      LockSemaphoreInfo(winsock_semaphore);
+    }
+  if (wsaData == (WSADATA *) NULL)
+    {
+      wsaData=(WSADATA *) AcquireMagickMemory(sizeof(WSADATA));
+      if (WSAStartup(MAKEWORD(2,2),wsaData) != 0)
+        ThrowFatalException(CacheFatalError,"WSAStartup failed");
+    }
+  if (use_lock)
+    UnlockSemaphoreInfo(winsock_semaphore);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 +  N T M a p M e m o r y                                                      %
 %                                                                             %
 %                                                                             %
@@ -2599,4 +2639,37 @@ MagickPrivate void NTWindowsGenesis(void)
     }
 #endif
 }
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   N T W i n d o w s T e r m i n u s                                         %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  NTWindowsTerminus() terminates the MagickCore Windows environment.
+%
+%  The format of the NTWindowsTerminus method is:
+%
+%      void NTWindowsTerminus(void)
+%
+*/
+MagickPrivate void NTWindowsTerminus(void)
+{
+  NTGhostscriptUnLoadDLL();
+  if (winsock_semaphore == (SemaphoreInfo *) NULL)
+    ActivateSemaphoreInfo(&winsock_semaphore);
+  LockSemaphoreInfo(winsock_semaphore);
+  if (wsaData != (WSADATA *) NULL)
+    {
+      WSACleanup();
+      (void *) RelinquishMagickMemory((void *) wsaData);
+    }
+  UnlockSemaphoreInfo(winsock_semaphore);
+  RelinquishSemaphoreInfo(&winsock_semaphore);
+}
 #endif
index 7f315fdfdbcb218035e361d68d339f6f57dc723b..c434028d759bf9f44419506716b1641e41a04dd2 100644 (file)
@@ -121,7 +121,10 @@ extern "C" {
 # include <pthread.h>
 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
 #  define MAGICKCORE_HAVE_WINTHREADS  1
+#include <winsock2.h>
+#include <ws2tcpip.h>
 #include <windows.h>
+#pragma comment (lib, "ws2_32.lib")
 #endif
 #if defined(MAGICKCORE_HAVE_SYS_SYSLIMITS_H)
 # include <sys/syslimits.h>