QueuesAPI.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.ibm.com/developerworks/oss/CPLv1.0.htm */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 
39 #include "rexx.h"
40 #include "LocalAPIManager.hpp"
41 #include "LocalQueueManager.hpp"
42 #include "LocalAPIContext.hpp"
43 #include "RexxAPI.h"
44 #include "RexxInternalApis.h"
45 
46 // the generated name pattern is
47 #define INTERNALNAME_MINIMUM ((sizeof(void *) * 4) + 3)
48 
49 /*********************************************************************/
50 /* */
51 /* Function: RexxCreateQueue() */
52 /* */
53 /* Description: API Entry to create a queue. */
54 /* */
55 /* Function: Create a new (empty) queue. */
56 /* */
57 /* Notes: Queues are assigned an internal name */
58 /* derived from the session that created them */
59 /* and the serial number of the queue. When a */
60 /* queue is deleted, its serial number becomes */
61 /* reuseable. */
62 /* */
63 /* The queue header blocks are stored in order */
64 /* of their serial number. The first queue */
65 /* created has serial number 1. Serial number 0 */
66 /* is reserved for the session queue. */
67 /* */
68 /* Before a queue is created, the chain of queue */
69 /* headers is searched for gaps. If we find a */
70 /* gap in the sequence, we use the number that */
71 /* belongs to the gap. This is somewhat */
72 /* inefficient, but has the advantages of */
73 /* simplicity, reliability and understandability. */
74 /* */
75 /* The user can pass a NULL for the requested queue*/
76 /* name. In that case, we assign an arbitrary */
77 /* name. */
78 /* */
79 /* If the requested name already exists, we assign */
80 /* an arbitrary name to the new queue. This name */
81 /* is passed back to the caller, and the duplicate */
82 /* flag is set. */
83 /* */
84 /* Queue names must obey the rules for REXX */
85 /* symbols. Lower case characters in queue names */
86 /* are translated to upper case. */
87 /* */
88 /* Input: Buffer for the name of the created queue. */
89 /* Size of this buffer. */
90 /* Requested queue name. May be NULL. */
91 /* */
92 /* Output: Internal name for the queue. Duplicate */
93 /* indicator. Status of create. */
94 /* */
95 /* Effects: New queue created. */
96 /* */
97 /*********************************************************************/
99  char *name, /* Internal name (returned). */
100  size_t size, /* Length of name buffer. */
101  const char *userRequested, /* Desired name. */
102  size_t *pdup) /* Duplicate name flag. */
103 {
105  {
106  // no user requested name, we'll generate one automatically
107  if (userRequested != NULL)
108  {
109  // we copy the queue name back into the user's buffer, so this space
110  // must be at least big enough for the requested name
111  if (strlen(userRequested) >= size)
112  {
113  throw new ServiceException(MEMORY_ERROR, "Unsufficient space for created queue name");
114  }
115  }
116  return lam->queueManager.createNamedQueue(userRequested, size, name, pdup);
117  }
118  EXIT_REXX_API();
119 }
120 
121 
122 /**
123  * Get access to a named queue, creating it if necessary.
124  *
125  * @param name The name of the desired queue.
126  * @param pdup A flag indicating whether the queue already existed.
127  *
128  * @return 0 if the queue was accessed ok, otherwise the error code
129  * for any errors.
130  */
131 RexxReturnCode RexxEntry RexxOpenQueue(const char *name, size_t *pdup)
132 {
134  {
135  return lam->queueManager.openNamedQueue(name, pdup);
136  }
137  EXIT_REXX_API();
138 }
139 
140 
141 /**
142  * Check to see if a given named queue exists
143  *
144  * @param name The name of the desired queue.
145  *
146  * @return 0 if the queue was accessed ok, otherwise the error code
147  * for any errors.
148  */
150 {
152  {
153  return lam->queueManager.queryNamedQueue(name);
154  }
155  EXIT_REXX_API();
156 }
157 
158 
159 /*********************************************************************/
160 /* */
161 /* Function: RexxDeleteQueue() */
162 /* */
163 /* Description: Delete a queue. */
164 /* */
165 /* Function: Delete all entries in a queue, then delete */
166 /* the queue header. */
167 /* */
168 /* Notes: Must tell the queue data manager to */
169 /* delete the queue entries. */
170 /* */
171 /* Input: external queue name. */
172 /* */
173 /* Effects: Queue and all its entries deleted. */
174 /* */
175 /*********************************************************************/
177  const char *name) /* name of queue to delete */
178 {
180  {
181  return lam->queueManager.deleteNamedQueue(name);
182  }
183  EXIT_REXX_API();
184 }
185 
186 
187 /*********************************************************************/
188 /* */
189 /* Function: RexxClearQueue() */
190 /* */
191 /* Description: Clear a queue. */
192 /* */
193 /* Function: Clear all entries in a queue; */
194 /* */
195 /* Input: external queue name. */
196 /* */
197 /* Effects: All entries in the queue are removed. */
198 /* */
199 /*********************************************************************/
201  const char *name) /* name of queue to delete */
202 {
204  {
205  // "SESSION" means get the session queue
206  if (lam->queueManager.isSessionQueue(name))
207  {
208  return lam->queueManager.clearSessionQueue();
209  }
210  else
211  {
212  return lam->queueManager.clearNamedQueue(name);
213  }
214  }
215  EXIT_REXX_API();
216 }
217 
218 
219 /*********************************************************************/
220 /* */
221 /* Function: RexxQueryQueue() */
222 /* */
223 /* Description: Return size of a named queue. */
224 /* */
225 /* Function: Return the count of elements in a named queue. */
226 /* */
227 /* Input: external queue name */
228 /* */
229 /* Effects: Count of queue elements. */
230 /* */
231 /*********************************************************************/
233  const char *name, /* Queue to query. */
234  size_t *count) /* Length of queue (returned) */
235 {
237  {
238  // "SESSION" means get the session queue
239  if (lam->queueManager.isSessionQueue(name))
240  {
241  return lam->queueManager.getSessionQueueCount(*count);
242  }
243  else
244  {
245  return lam->queueManager.getQueueCount(name, *count);
246  }
247  }
248  EXIT_REXX_API();
249 }
250 
251 
252 /*********************************************************************/
253 /* */
254 /* Function: RexxAddQueue() */
255 /* */
256 /* Description: Add entry to a queue. */
257 /* */
258 /* Function: Allocate memory for queue entry and control */
259 /* block. Move data into entry & set up */
260 /* control info. Add entry to queue chain. */
261 /* */
262 /* Input: external queue name, entry data, data size, */
263 /* LIFO/FIFO flag. */
264 /* */
265 /* Effects: Memory allocated for entry. Entry added to */
266 /* queue. */
267 /* */
268 /*********************************************************************/
270  const char *name,
271  PCONSTRXSTRING data,
272  size_t flag)
273 {
275  {
276  /* first check the flag */
277  if (flag != RXQUEUE_FIFO && flag != RXQUEUE_LIFO)
278  {
279  return RXQUEUE_BADWAITFLAG;
280  }
281  if (lam->queueManager.isSessionQueue(name))
282  {
283  return lam->queueManager.addToSessionQueue(*data, flag);
284  }
285  else
286  {
287  return lam->queueManager.addToNamedQueue(name, *data, flag);
288  }
289  }
290  EXIT_REXX_API();
291 }
292 
293 /*********************************************************************/
294 /* */
295 /* Function: RexxPullFromQueue() */
296 /* */
297 /* Description: Pull an entry from a queue. */
298 /* */
299 /* Function: Locate the queue, return its top entry to */
300 /* the caller, and tell the queue data */
301 /* manager to delete the entry. */
302 /* */
303 /* If the queue is empty, the caller can elect */
304 /* to wait for someone to post an entry. */
305 /* */
306 /* Notes: Caller is responsible for freeing the returned */
307 /* memory. */
308 /* */
309 /* The entry's control block is stored in the */
310 /* entry's memory. We must therefore obtain */
311 /* addressability to the entry's memory before */
312 /* we can process the entry. */
313 /* */
314 /* Input: external queue name, wait flag. */
315 /* */
316 /* Output: queue element, data size, date/time stamp. */
317 /* */
318 /* Effects: Top entry removed from the queue. Message */
319 /* queued to the queue data manager. */
320 /* */
321 /*********************************************************************/
323  const char *name,
324  RXSTRING *data_buf,
325  RexxQueueTime *time,
326  size_t waitflag)
327 {
329  {
330  /* first check the flag */
331  if (waitflag != RXQUEUE_NOWAIT && waitflag != RXQUEUE_WAIT)
332  {
333  return RXQUEUE_BADWAITFLAG;
334  }
335  // we use a common path here, because pull is more complicated.
336  // NULL for the name is the signal to use the session queue.
337  if (lam->queueManager.isSessionQueue(name))
338  {
339  name = NULL;
340  }
341  return lam->queueManager.pullFromQueue(name, *data_buf, waitflag, time);
342  }
343  EXIT_REXX_API();
344 }
345 
346 /*********************************************************************/
347 /* */
348 /* Function: Indicated a process is terminating and should */
349 /* remove a reference to the session queue */
350 /* Description: Close the session queue */
351 /* */
352 /*********************************************************************/
354 {
355  // this shuts down the entire environment
357  return RXQUEUE_OK;
358 }
359 
360 
361 /**
362  * Initialize the API subsystem at process startup.
363  *
364  * @return Always returns 0;
365  */
367 {
368  // this will initialize the API subsystem
370  {
371  return 0;
372  }
373  EXIT_REXX_API();
374 
375 }
RexxReturnCode RexxEntry RexxCreateSessionQueue()
Definition: QueuesAPI.cpp:366
RexxReturnCode RexxEntry RexxPullFromQueue(const char *name, RXSTRING *data_buf, RexxQueueTime *time, size_t waitflag)
Definition: QueuesAPI.cpp:322
RexxReturnCode RexxEntry RexxQueryQueue(const char *name, size_t *count)
Definition: QueuesAPI.cpp:232
RexxReturnCode RexxEntry RexxAddQueue(const char *name, PCONSTRXSTRING data, size_t flag)
Definition: QueuesAPI.cpp:269
RexxReturnCode RexxEntry RexxDeleteQueue(const char *name)
Definition: QueuesAPI.cpp:176
RexxReturnCode RexxEntry RexxOpenQueue(const char *name, size_t *pdup)
Definition: QueuesAPI.cpp:131
RexxReturnCode RexxEntry RexxDeleteSessionQueue()
Definition: QueuesAPI.cpp:353
RexxReturnCode RexxEntry RexxCreateQueue(char *name, size_t size, const char *userRequested, size_t *pdup)
Definition: QueuesAPI.cpp:98
RexxReturnCode RexxEntry RexxClearQueue(const char *name)
Definition: QueuesAPI.cpp:200
RexxReturnCode RexxEntry RexxQueueExists(const char *name)
Definition: QueuesAPI.cpp:149
#define ENTER_REXX_API(target)
Definition: RexxAPI.h:49
#define EXIT_REXX_API()
Definition: RexxAPI.h:55
@ MEMORY_ERROR
@ QueueManager
static void shutdownInstance()
CONSTANT_RXSTRING * PCONSTRXSTRING
Definition: rexx.h:186
int RexxReturnCode
Definition: rexx.h:73
#define RexxEntry
Definition: rexx.h:412
#define RXQUEUE_BADWAITFLAG
Definition: rexxapidefs.h:257
#define RXQUEUE_WAIT
Definition: rexxapidefs.h:243
#define RXQUEUE_OK
Definition: rexxapidefs.h:248
#define RXQUEUE_FIFO
Definition: rexxapidefs.h:239
#define RXQUEUE_LIFO
Definition: rexxapidefs.h:240
#define RXQUEUE_NOWAIT
Definition: rexxapidefs.h:242