From 0bc5220b6c01ee338358de7f19080f1d19d21d58 Mon Sep 17 00:00:00 2001 From: dirk Date: Mon, 22 Dec 2014 01:38:36 +0000 Subject: [PATCH] Added support for distributed pixel cache to the Windows distribution. --- MagickCore/distribute-cache.c | 99 +++++++++++++++++++++++++---------- MagickCore/magick.c | 2 +- MagickCore/nt-base-private.h | 6 ++- MagickCore/nt-base.c | 75 +++++++++++++++++++++++++- MagickCore/studio.h | 3 ++ 5 files changed, 152 insertions(+), 33 deletions(-) diff --git a/MagickCore/distribute-cache.c b/MagickCore/distribute-cache.c index ada74191e..e1a2022a2 100644 --- a/MagickCore/distribute-cache.c +++ b/MagickCore/distribute-cache.c @@ -73,11 +73,25 @@ #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 #include #include #include +#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 } diff --git a/MagickCore/magick.c b/MagickCore/magick.c index 23bb336c3..718d27bcf 100644 --- a/MagickCore/magick.c +++ b/MagickCore/magick.c @@ -1382,7 +1382,7 @@ MagickExport void MagickCoreTerminus(void) TypeComponentTerminus(); ColorComponentTerminus(); #if defined(MAGICKCORE_WINDOWS_SUPPORT) - NTGhostscriptUnLoadDLL(); + NTWindowsTerminus(); #endif MagicComponentTerminus(); DelegateComponentTerminus(); diff --git a/MagickCore/nt-base-private.h b/MagickCore/nt-base-private.h index cb3b32ae1..bb4761471 100644 --- a/MagickCore/nt-base-private.h +++ b/MagickCore/nt-base-private.h @@ -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 */ diff --git a/MagickCore/nt-base.c b/MagickCore/nt-base.c index fadd42fd2..c4d96969c 100644 --- a/MagickCore/nt-base.c +++ b/MagickCore/nt-base.c @@ -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; 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); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % + N T M a p M e m o r y % % % % % @@ -2599,4 +2639,37 @@ MagickPrivate void NTWindowsGenesis(void) } #endif } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% 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 diff --git a/MagickCore/studio.h b/MagickCore/studio.h index 7f315fdfd..c434028d7 100644 --- a/MagickCore/studio.h +++ b/MagickCore/studio.h @@ -121,7 +121,10 @@ extern "C" { # include #elif defined(MAGICKCORE_WINDOWS_SUPPORT) # define MAGICKCORE_HAVE_WINTHREADS 1 +#include +#include #include +#pragma comment (lib, "ws2_32.lib") #endif #if defined(MAGICKCORE_HAVE_SYS_SYSLIMITS_H) # include -- 2.40.0