]> granicus.if.org Git - imagemagick/blob - MagickCore/distribute-cache.c
(no commit message)
[imagemagick] / MagickCore / distribute-cache.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
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   %
10 %                                                                             %
11 %                      CCCC   AAA    CCCC  H   H  EEEEE                       %
12 %                     C      A   A  C      H   H  E                           %
13 %                     C      AAAAA  C      HHHHH  EEE                         %
14 %                     C      A   A  C      H   H  E                           %
15 %                      CCCC  A   A   CCCC  H   H  EEEEE                       %
16 %                                                                             %
17 %                                                                             %
18 %                 MagickCore Distributed Pixel Cache Methods                  %
19 %                                                                             %
20 %                              Software Design                                %
21 %                                John Cristy                                  %
22 %                                January 2013                                 %
23 %                                                                             %
24 %                                                                             %
25 %  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
26 %  dedicated to making software imaging solutions freely available.           %
27 %                                                                             %
28 %  You may not use this file except in compliance with the License.  You may  %
29 %  obtain a copy of the License at                                            %
30 %                                                                             %
31 %    http://www.imagemagick.org/script/license.php                            %
32 %                                                                             %
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.                                             %
38 %                                                                             %
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 %
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.
48 %
49 */
50 \f
51 /*
52   Include declarations.
53 */
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>
65 #include <netdb.h>
66 #endif
67 \f
68 /*
69 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 %                                                                             %
71 %                                                                             %
72 %                                                                             %
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                       %
74 %                                                                             %
75 %                                                                             %
76 %                                                                             %
77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 %
79 %  AcquireDistributeCacheInfo() allocates the DistributeCacheInfo structure.
80 %
81 %  The format of the AcquireDistributeCacheInfo method is:
82 %
83 %      DistributeCacheInfo *AcquireDistributeCacheInfo(ExceptionInfo *exception)
84 %
85 %  A description of each parameter follows:
86 %
87 %    o exception: return any errors or warnings in this structure.
88 %
89 */
90 MagickPrivate DistributeCacheInfo *AcquireDistributeCacheInfo(
91   ExceptionInfo *exception)
92 {
93 #if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_HAVE_PTHREAD)
94   DistributeCacheInfo
95     *distribute_cache_info;
96
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);
106 #else
107   return((DistributeCacheInfo *) NULL);
108 #endif
109 }
110 \f
111 /*
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 %                                                                             %
114 %                                                                             %
115 %                                                                             %
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                       %
117 %                                                                             %
118 %                                                                             %
119 %                                                                             %
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 %
122 %  DestroyDistributeCacheInfo() deallocates memory associated with an
123 %  DistributeCacheInfo structure.
124 %
125 %  The format of the DestroyDistributeCacheInfo method is:
126 %
127 %      DistributeCacheInfo *DestroyDistributeCacheInfo(
128 %        DistributeCacheInfo *distribute_cache_info)
129 %
130 %  A description of each parameter follows:
131 %
132 %    o distribute_cache_info: the distributed cache info.
133 %
134 */
135 MagickPrivate DistributeCacheInfo *DestroyDistributeCacheInfo(
136   DistributeCacheInfo *distribute_cache_info)
137 {
138   assert(distribute_cache_info != (DistributeCacheInfo *) NULL);
139   assert(distribute_cache_info->signature == MagickSignature);
140 #if defined(MAGICKCORE_HAVE_SOCKET)
141 #endif
142   distribute_cache_info->signature=(~MagickSignature);
143   distribute_cache_info=(DistributeCacheInfo *)
144     RelinquishMagickMemory(distribute_cache_info);
145   return(distribute_cache_info);
146 }
147 \f
148 /*
149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 %                                                                             %
151 %                                                                             %
152 %                                                                             %
153 +   P i x e l C a c h e S e r v e r                                           %
154 %                                                                             %
155 %                                                                             %
156 %                                                                             %
157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 %
159 %  PixelCacheServer() waits on the specified port for commands to create, read,
160 %  update, or destroy a pixel cache.
161 %
162 %  The format of the PixelCacheServer() method is:
163 %
164 %      void PixelCacheServer(const size_t port)
165 %
166 %  A description of each parameter follows:
167 %
168 %    o port: connect the distributed pixel cache at this port.
169 %
170 */
171 MagickExport void PixelCacheServer(const size_t port)
172 {
173 #if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_HAVE_PTHREAD)
174   char
175     message[MaxTextExtent],
176     service[MaxTextExtent];
177
178   int
179     file,
180     status;
181
182   register struct addrinfo
183     *p;
184
185   ssize_t
186     count;
187
188   socklen_t
189     length;
190
191   struct addrinfo
192     hints,
193     *result;
194
195   struct sockaddr_storage
196     address;
197
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);
205   if (status != 0)
206     {
207       (void) fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(status));
208       exit(EXIT_FAILURE);
209     }
210   for (p=result; p != (struct addrinfo *) NULL; p=p->ai_next)
211   {
212     file=socket(p->ai_family, p->ai_socktype,p->ai_protocol);
213     if (file == -1)
214       continue;
215     if (bind(file,p->ai_addr,p->ai_addrlen) == 0)
216       break;
217     (void) close(file);
218   }
219   if (p == NULL)
220     {
221       (void) fprintf(stderr,"Could not bind\n");
222       exit(EXIT_FAILURE);
223     }
224   freeaddrinfo(result);
225   for ( ; ; )
226   {
227     char
228       host[NI_MAXHOST],
229       service[NI_MAXSERV];
230
231     ssize_t
232       bytes;
233
234     length=(socklen_t) sizeof(struct sockaddr_storage);
235     count=recvfrom(file,message,MaxTextExtent,0,(struct sockaddr *) &address,
236       &length);
237     if (count == -1)
238       continue;
239     status=getnameinfo((struct sockaddr *) &address,length,host,NI_MAXHOST,
240       service,NI_MAXSERV,NI_NUMERICSERV);
241     if (status == 0)
242       (void) printf("received %ld bytes from %s:%s\n",(long) count,host,
243         service);
244     else
245       (void) fprintf(stderr,"getnameinfo: %s\n", gai_strerror(status));
246     bytes=sendto(file,message,(size_t) count,0,(struct sockaddr *) &address,
247       length);
248     if (bytes != count)
249       (void) fprintf(stderr,"error sending response\n");
250   }
251 #else
252   (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
253     "DelegateLibrarySupportNotBuiltIn","'%s' (socket)",image_info->filename);
254 #endif
255 }