2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % DDDD IIIII SSSSS TTTTT RRRR IIIII BBBB U U TTTTT EEEEE %
6 % D D I SS T R R I B B U U T E %
7 % D D I SSS T RRRR I BBBB U U T EEE %
8 % D D I SS T R R I B B U U T E %
9 % DDDDA IIIII SSSSS T R R IIIII BBBB UUU T EEEEE %
11 % CCCC AAA CCCC H H EEEEE %
13 % C AAAAA C HHHHH EEE %
15 % CCCC A A CCCC H H EEEEE %
18 % MagickCore Distributed Pixel Cache Methods %
25 % Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
26 % dedicated to making software imaging solutions freely available. %
28 % You may not use this file except in compliance with the License. You may %
29 % obtain a copy of the License at %
31 % http://www.imagemagick.org/script/license.php %
33 % Unless required by applicable law or agreed to in writing, software %
34 % distributed under the License is distributed on an "AS IS" BASIS, %
35 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
36 % See the License for the specific language governing permissions and %
37 % limitations under the License. %
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 % A distributed pixel cache is an extension of the traditional pixel cache
42 % available on a single host. The distributed pixel cache may span multiple
43 % servers so that it can grow in size and transactional capacity to support
44 % very large images. Start up the pixel cache server on one or more machines.
45 % When you read or operate on an image and the local pixel cache resources are
46 % exhausted, ImageMagick contacts one or more of these remote pixel servers to
47 % store or retrieve pixels.
54 #include "MagickCore/studio.h"
55 #include "MagickCore/distribute-cache.h"
56 #include "MagickCore/distribute-cache-private.h"
57 #include "MagickCore/exception.h"
58 #include "MagickCore/exception-private.h"
59 #include "MagickCore/locale_.h"
60 #include "MagickCore/memory_.h"
61 #include "MagickCore/registry.h"
62 #include "MagickCore/string_.h"
63 #if defined(MAGICKCORE_HAVE_SOCKET)
64 #include <sys/socket.h>
69 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 % A c q u i r e D i s t r i b u t e C a c h e I n f o %
77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79 % AcquireDistributeCacheInfo() allocates the DistributeCacheInfo structure.
81 % The format of the AcquireDistributeCacheInfo method is:
83 % DistributeCacheInfo *AcquireDistributeCacheInfo(ExceptionInfo *exception)
85 % A description of each parameter follows:
87 % o exception: return any errors or warnings in this structure.
90 MagickPrivate DistributeCacheInfo *AcquireDistributeCacheInfo(
91 ExceptionInfo *exception)
93 #if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_HAVE_PTHREAD)
95 *distribute_cache_info;
97 distribute_cache_info=(DistributeCacheInfo *) NULL;
98 distribute_cache_info=(DistributeCacheInfo *) AcquireMagickMemory(
99 sizeof(*distribute_cache_info));
100 if (distribute_cache_info == (DistributeCacheInfo *) NULL)
101 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
102 (void) ResetMagickMemory(distribute_cache_info,0,
103 sizeof(*distribute_cache_info));
104 distribute_cache_info->signature=MagickSignature;
105 return(distribute_cache_info);
107 return((DistributeCacheInfo *) NULL);
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 % D e s t r o y D i s t r i b u t e C a c h e I n f o %
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 % DestroyDistributeCacheInfo() deallocates memory associated with an
123 % DistributeCacheInfo structure.
125 % The format of the DestroyDistributeCacheInfo method is:
127 % DistributeCacheInfo *DestroyDistributeCacheInfo(
128 % DistributeCacheInfo *distribute_cache_info)
130 % A description of each parameter follows:
132 % o distribute_cache_info: the distributed cache info.
135 MagickPrivate DistributeCacheInfo *DestroyDistributeCacheInfo(
136 DistributeCacheInfo *distribute_cache_info)
138 assert(distribute_cache_info != (DistributeCacheInfo *) NULL);
139 assert(distribute_cache_info->signature == MagickSignature);
140 #if defined(MAGICKCORE_HAVE_SOCKET)
142 distribute_cache_info->signature=(~MagickSignature);
143 distribute_cache_info=(DistributeCacheInfo *)
144 RelinquishMagickMemory(distribute_cache_info);
145 return(distribute_cache_info);
149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153 + P i x e l C a c h e S e r v e r %
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159 % PixelCacheServer() waits on the specified port for commands to create, read,
160 % update, or destroy a pixel cache.
162 % The format of the PixelCacheServer() method is:
164 % void PixelCacheServer(const size_t port)
166 % A description of each parameter follows:
168 % o port: connect the distributed pixel cache at this port.
171 MagickExport void PixelCacheServer(const size_t port)
173 #if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_HAVE_PTHREAD)
175 message[MaxTextExtent],
176 service[MaxTextExtent];
182 register struct addrinfo
195 struct sockaddr_storage
198 (void) ResetMagickMemory(&hints,0,sizeof(hints));
199 hints.ai_family=AF_UNSPEC; /* allow IPv4 or IPv6 */
200 hints.ai_socktype=SOCK_DGRAM; /* datagram socket */
201 hints.ai_flags=AI_PASSIVE; /* for wildcard IP address */
202 hints.ai_protocol=0; /* any protocol */
203 (void) FormatLocaleString(service,MaxTextExtent,"%.20g",(double) port);
204 status=getaddrinfo((const char *) NULL,service,&hints,&result);
207 (void) fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(status));
210 for (p=result; p != (struct addrinfo *) NULL; p=p->ai_next)
212 file=socket(p->ai_family, p->ai_socktype,p->ai_protocol);
215 if (bind(file,p->ai_addr,p->ai_addrlen) == 0)
221 (void) fprintf(stderr,"Could not bind\n");
224 freeaddrinfo(result);
234 length=(socklen_t) sizeof(struct sockaddr_storage);
235 count=recvfrom(file,message,MaxTextExtent,0,(struct sockaddr *) &address,
239 status=getnameinfo((struct sockaddr *) &address,length,host,NI_MAXHOST,
240 service,NI_MAXSERV,NI_NUMERICSERV);
242 (void) printf("received %ld bytes from %s:%s\n",(long) count,host,
245 (void) fprintf(stderr,"getnameinfo: %s\n", gai_strerror(status));
246 bytes=sendto(file,message,(size_t) count,0,(struct sockaddr *) &address,
249 (void) fprintf(stderr,"error sending response\n");
252 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
253 "DelegateLibrarySupportNotBuiltIn","'%s' (socket)",image_info->filename);