With FairCom DB server-side queues, client programs, connected to the same server, can pass information among each other, emulating a powerful inter-process communications mechanism that is portable, scalable and distributed.
FairCom DB server-side queues, also referred to as "system queues," extend the concepts of c-tree inter-thread queue routines by providing two additional features:
- Server-side queues operate across the client/server boundary.
- Server-side queues can be named so that different clients connected to the same FairCom Server may share the same queue.
Server-side queues provide the foundation on which the FairCom Server’s file notification feature is built. See the next chapter in this guide for details on the file notification feature.
Using Server-Side Queues
This section discusses the tasks involved in using system queues:
- Creating or opening a server-side (system) queue
- Writing to a system queue
- Reading from a system queue
- Retrieving the size of the next message in a system queue
- Retrieving the number of messages in a system queue
- Closing a system queue
The next sections explain these tasks in detail.
LKSHlksh
Creating or Opening a Server-Side Queue
Before any operation can be attempted with a server-side queue (system queue), a process must create a new queue, or open an existing queue, by calling the function:
ctCONV NINT ctDECL ctSysQueueOpen(pTEXT qname,NINT qmode);
Parameter qname identifies the queue to be opened. If the queue specified by qname does not exist, a new queue is created. Parameter qmode is currently reserved for future use and should be set to zero. ctSysQueueOpen() returns a queue handle on success, or a negative number as the error code.
Example
#include <ctreep.h>
int main(void)
{
NINT eRet = 0;
NINT hQueue = -1;
TEXT buffer[256];
NINT isam_init = 0;
/* init ISAM */
eRet = (NINT)INTISAMX(6, 7, 4, 6, 0, "ADMIN", "ADMIN", "FAIRCOMS");
if (eRet != NO_ERROR)
{
printf("INTISAM failed with error %d\n", eRet);
goto Exit;
}
isam_init++;
/* create a new queue */
hQueue = ctSysQueueOpen("MyQueue", 0);
if (hQueue < 0)
{
eRet = -hQueue;
printf("ctSysQueueOpen failed with error %d\n", eRet);
goto Exit;
}
/* wait 100 ms for a new message */
eRet = ctSysQueueRead(hQueue, buffer, sizeof(buffer), 100);
/* check if read time-out */
if (eRet == NO_ERROR)
printf("ctSysQueueRead succeeded\n");
else if (eRet == NTIM_ERR)
printf("ctSysQueueRead time-out\n");
else
printf("ctSysQueueRead failed with error %d\n", eRet);
Exit:
/* close the queue */
if (hQueue >= 0)
{
eRet = ctSysQueueClose(hQueue);
if (eRet != NO_ERROR)
printf("ctSysQueueClose failed with error %d\n", eRet);
}
if (isam_init)
CLISAM();
return (int)eRet;
}
Writing to a Server-Side Queue
Data is placed on the queue by invoking ctSysQueueWrite() or ctSysQueueLIFOWrite() functions. ctSysQueueWrite() adds new data at the end of the queue, while the ctSysQueueLIFOWrite() function adds the data at the beginning of the queue, similar to a stack operation. The syntax for the server-side queue (system queue) write functions is shown here:
ctCONV NINT ctDECL ctSysQueueWrite(NINT qhandle,pVOID message,NINT msglen)
ctCONV NINT ctDECL ctSysQueueLIFOWrite(NINT qhandle,pVOID message,
NINT msglen)
Parameter qhandle is a system queue handle returned by a call to ctSysQueueOpen(). Parameter message is a pointer to a block of memory containing arbitrary data to be placed on the queue and msglen indicates how many bytes are pointed to by message. ctSysQueueWrite() and ctSysQueueLIFOWrite() return NO_ERROR (0) on success.
Example using ctSysQueueWrite:
#include <ctreep.h>
int main(void)
{
NINT eRet = 0;
NINT hQueue = -1;
TEXT buffer[256];
NINT isam_init = 0;
/* init ISAM */
eRet = (NINT)INTISAMX(6, 7, 4, 6, 0, "ADMIN", "ADMIN", "FAIRCOMS");
if (eRet != NO_ERROR)
{
printf("INTISAM failed with error %d\n", eRet);
goto Exit;
}
isam_init++;
/* create a new queue */
hQueue = ctSysQueueOpen("MyQueue", 0);
if (hQueue < 0)
{
eRet = -hQueue;
printf("ctSysQueueOpen failed with error %d\n", eRet);
goto Exit;
}
/* write text to a queue */
eRet = ctSysQueueWrite(hQueue, "This is the first line", 22);
if (eRet != NO_ERROR)
{
printf("ctSysQueueWrite failed with error %d\n", eRet);
goto Exit;
}
/* read the message in the queue */
eRet = ctSysQueueRead(hQueue, buffer, sizeof(buffer), ctWAITFOREVER);
/* check if read time-out */
if (eRet == NO_ERROR)
printf("Read: %s\n", buffer);
else if (eRet == NTIM_ERR)
printf("ctSysQueueRead time-out\n");
else
printf("ctSysQueueRead failed with error %d\n", eRet);
Exit:
/* close the queue */
if (hQueue >= 0)
{
eRet = ctSysQueueClose(hQueue);
if (eRet != NO_ERROR)
printf("ctSysQueueClose failed with error %d\n", eRet);
}
if (isam_init)
CLISAM();
return (int)eRet;
}
Example with ctSysQueueLIFOWrite
#include <ctreep.h>
int main(void)
{
NINT eRet = 0;
NINT hQueue = -1;
TEXT buffer[256];
NINT isam_init = 0;
NINT i;
/* init ISAM */
eRet = (NINT)INTISAMX(6, 7, 4, 6, 0, "ADMIN", "ADMIN", "FAIRCOMS");
if (eRet != NO_ERROR)
{
printf("INTISAM failed with error %d\n", eRet);
goto Exit;
}
isam_init++;
/* create a new queue */
hQueue = ctSysQueueOpen("MyQueue", 0);
if (hQueue < 0)
{
eRet = -hQueue;
printf("ctSysQueueOpen failed with error %d\n", eRet);
goto Exit;
}
/* write text to a queue using ctSysQueueWrite */
eRet = ctSysQueueWrite(hQueue, "This is the first line", 23);
if (eRet != NO_ERROR)
{
printf("ctSysQueueWrite failed with error %d\n", eRet);
goto Exit;
}
/* write text to a queue using ctSysQueueLIFOWrite */
eRet = ctSysQueueLIFOWrite(hQueue, "This line should be on top", 27);
if (eRet != NO_ERROR)
{
printf("ctSysQueueLIFOWrite failed with error %d\n", eRet);
goto Exit;
}
/* read two messages from the queue */
for (i = 0; i < 2; i++)
{
eRet = ctSysQueueRead(hQueue, buffer, sizeof(buffer), ctWAITFOREVER);
/* check if read time-out */
if (eRet == NO_ERROR)
printf("Read %d: %s\n", (i+1), buffer);
else if (eRet == NTIM_ERR)
printf("ctSysQueueRead time-out\n");
else
printf("ctSysQueueRead failed with error %d\n", eRet);
}
Exit:
/* close the queue */
if (hQueue >= 0)
{
eRet = ctSysQueueClose(hQueue);
if (eRet != NO_ERROR)
printf("ctSysQueueClose failed with error %d\n", eRet);
}
if (isam_init)
CLISAM();
return (int)eRet;
}
Reading from a Server-Side Queue
Data is read from the beginning of a server-side queue (system queue) by calling the function ctSysQueueRead(). The syntax is:
ctCONV NINT ctDECL ctSysQueueRead(NINT qhandle, pVOID buffer, NINT buflen,
LONG timeout)
Parameter qhandle is a system queue handle returned by a call to ctSysQueueOpen(). The timeout parameter specifies the time in milliseconds that ctSysQueueRead() will block waiting for data. Specifying ctWAITFOREVER for the timeout parameter causes ctSysQueueRead() to block until data is available in the queue. Parameter buffer is a pointer to a memory block large enough to hold the next message in the queue, and buflen indicates the size in bytes of buffer. ctSysQueueRead() returns NO_ERROR (0) on success. ctSysQueueRead() returns error NTIM_ERR (156, timeout) if the time specified by timeout parameter expires and no message is available.
For code examples on how to use ctSysQueueRead(), please see the examples provided in Creating or Opening a Server-Side Queue and Writing to a Server-Side Queue.
Retrieving the Size of the Next Message in a Server-Side Queue
The ctSysQueueMlen() function can be used to obtain the length of the next available message on the server-side queue (system queue). The syntax for ctSysQueueMlen() is:
ctCONV NINT ctDECL ctSysQueueMlen(NINT qhandle,LONG timeout)
Parameter qhandle is a system queue handle returned by a call to ctSysQueueOpen(). Parameter timeout specifies a time in milliseconds that ctSysQueueMlen() will block if the queue is empty. A timeout value of ctWAITFOREVER causes ctSysQueueMlen() to block until data is available in the queue. Use ctSysQueueMlen() to determine the appropriate size of a buffer before calling ctSysQueueRead(). ctSysQueueMlen() returns the length of the next available message, or a negative value on error.
Example
#include <ctreep.h>
int main(void)
{
NINT eRet = 0;
NINT hQueue = -1;
TEXT buffer[256];
NINT isam_init = 0;
NINT len;
/* init ISAM */
eRet = (NINT)INTISAMX(6, 7, 4, 6, 0, "ADMIN", "ADMIN", "FAIRCOMS");
if (eRet != NO_ERROR)
{
printf("INTISAM failed with error %d\n", eRet);
goto Exit;
}
isam_init++;
/* create a new queue */
hQueue = ctSysQueueOpen("MyQueue", 0);
if (hQueue < 0)
{
eRet = -hQueue;
printf("ctSysQueueOpen failed with error %d\n", eRet);
goto Exit;
}
/* write text to a queue using ctSysQueueWrite */
eRet = ctSysQueueWrite(hQueue, "This is the first line", 23);
if (eRet != NO_ERROR)
{
printf("ctSysQueueWrite failed with error %d\n", eRet);
goto Exit;
}
/* retrieve the size of the message in queue */
len = ctSysQueueMlen(hQueue, 100);
if (len < 0)
{
eRet = -len;
printf("ctSysQueueMlen failed with error %d\n", eRet);
goto Exit;
}
printf("Message length is %d\n", len);
/* check the len of the message */
if (len > sizeof(buffer))
{
printf("buffer is not large enough to receive message\n");
goto Exit;
}
eRet = ctSysQueueRead(hQueue, buffer, sizeof(buffer), ctWAITFOREVER);
/* check if read time-out */
if (eRet == NO_ERROR)
printf("Read: %s\n", buffer);
else if (eRet == NTIM_ERR)
printf("ctSysQueueRead time-out\n");
else
printf("ctSysQueueRead failed with error %d\n", eRet);
Exit:
/* close the queue */
if (hQueue >= 0)
{
eRet = ctSysQueueClose(hQueue);
if (eRet != NO_ERROR)
printf("ctSysQueueClose failed with error %d\n", eRet);
}
if (isam_init)
CLISAM();
return (int)eRet;
}
Retrieving the Number of Messages in a Server-Side Queue
ctSysQueueCount can be used to obtain the number of messages waiting in the server-side queue (system queue). The syntax for ctSysQueueCount() is:
ctCONV NINT ctDECL ctSysQueueCount(NINT qhandle)
Parameter qhandle is a system queue handle returned by a call to ctSysQueueOpen(). ctSysQueueCount() returns the number of messages in queue, or a negative number on error.
Example
#include <ctreep.h>
int main(void)
{
NINT eRet = 0;
NINT hQueue = -1;
NINT isam_init = 0;
NINT count;
/* init ISAM */
eRet = (NINT)INTISAMX(6, 7, 4, 6, 0, "ADMIN", "ADMIN", "FAIRCOMS");
if (eRet != NO_ERROR)
{
printf("INTISAM failed with error %d\n", eRet);
goto Exit;
}
isam_init++;
/* create a new queue */
hQueue = ctSysQueueOpen("MyQueue", 0);
if (hQueue < 0)
{
eRet = -hQueue;
printf("ctSysQueueOpen failed with error %d\n", eRet);
goto Exit;
}
/* retrieve the number of messages in queue */
count = ctSysQueueCount(hQueue);
if (count < 0)
{
eRet = -count;
printf("ctSysQueueCount failed with error %d\n", eRet);
goto Exit;
}
printf("Number of messages in queue: %d\n", count);
Exit:
/* close the queue */
if (hQueue >= 0)
{
eRet = ctSysQueueClose(hQueue);
if (eRet != NO_ERROR)
printf("ctSysQueueClose failed with error %d\n", eRet);
}
if (isam_init)
CLISAM();
return (int)eRet;
}
Closing a Server-Side Queue
When the server-side queue (system queue) is no longer needed, it must be closed by calling the close function:
ctCONV NINT ctDECL ctSysQueueClose(NINT qhandle)
Parameter qhandle is a system queue handle returned by a call to ctSysQueueOpen() function. ctSysQueueClose() returns NO_ERROR (0) on success.