Test auf exklusives Open einer Queue für Lesen und Schreiben

In diesem kleinen Beispiel möchte ich testen, wie ich eine Queue

  1. zum Lesen und Schreiben (für GET und PUT gleichzeitig)
  2. und zwar exklusiv (kein anderer Prozeß kann die Queue ansprechen)

…öffne.

Durch mehrfaches Starten des Programms, daß mehrere Instanzen dessen zeitgleich versuchen, auf die Queue zu zugreifen, kann man sehen, daß nur der erste Prozeß an die Queue ran kommt.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <cmqc.h>
 
#define MQM_NAME "MQM7"
#define Q_NAME "LQ.TEST_QUEUE_01"
#define MSG1 "Test-Message 1"
 
 
void EndOfPrg(int);
char *MqReasonToStr(MQLONG);
 
 
int main (int argc, char *argv[])
{
	MQCHAR48 qmName; // Queue Manager Name
	MQHCONN hCon; // Connection Handle für den MQM
	MQHOBJ hQueue1; // Object Handle für die Queue 1
	MQOD odQueue1 = { MQOD_DEFAULT }; // Object Descriptor für die Queue 1
	MQMD mdMsgGet = { MQMD_DEFAULT }; // Message Descriptor für die zu lesende Message
	MQMD mdMsgPut = { MQMD_DEFAULT }; // Message Descriptor für die zu schreibende Message
	MQGMO gmoMsgGet = { MQGMO_DEFAULT }; // Get Message Options für die zu lesende Message
	MQPMO pmoMsgPut = { MQPMO_DEFAULT }; // Put Message Options für zu schreibende Message
	MQLONG optionsQueue1MQOPEN; // MQOPEN Options (für die Queue 1)
	MQLONG optionsMQCLOSE; // MQCLOSE options
 
	MQLONG cComplMQCONN; // MQCONN Completion Code
	MQLONG cComplMQOPEN; // MQOPEN Completion Code
	MQLONG cComplMQGET; // MQGET Completion Code
	MQLONG cComplMQPUT; // MQPUT Completion Code
	MQLONG cComplMQCLOSE; // MQCLOSE Completion Code
	MQLONG cReasonMQCONN; // Reason Code für MQCONN
	MQLONG cReasonMQOPEN; // Reason Code für MQOPEN
	MQLONG cReasonMQGET; // Reason Code für MQGET
	MQLONG cReasonMQPUT; // Reason Code für MQPUT
	MQLONG cReasonMQCLOSE; // Reason Code für MQCLOSE
 
	MQCHAR bufferMsgGet[80]; // Message Buffer für die zu lesende Message
	MQCHAR bufferMsgPut[80]; // Message Buffer für die zu schreibende Message
	MQLONG datalen; // Datenmenge im Buffer
	int i;
 
	printf("==================== BEGIN ====================\n");
 
	memset(qmName, '\0', sizeof(qmName));
 
	// MQCONN
	strncpy(qmName, MQM_NAME, sizeof(qmName) - 1);
	printf("MQCONN: Connect zum MQM [%s]...\n", qmName);
 
	MQCONN(qmName, &hCon, &cComplMQCONN, &cReasonMQCONN); // Connect zum MQM
	if (cComplMQCONN == MQCC_FAILED)
	{
		printf("MQCONN Fehler: Reason Code = [%ld]\n", cReasonMQCONN);
		EndOfPrg(cReasonMQCONN);
	} // if
	printf("MQCONN: erfolgreich\n");
 
	system("pause");
 
	// MQOPEN
	strncpy(odQueue1.ObjectName, Q_NAME, MQ_Q_NAME_LENGTH - 1);
	printf("MQOPEN: Queue [%s] wird geöffnet...\n", odQueue1.ObjectName);
 
	optionsQueue1MQOPEN = MQOO_INPUT_EXCLUSIVE + MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING; // Input noshare, Output, nicht wenn MQM runtergefahren wird
	printf("Optionen: MQOO_INPUT_EXCLUSIVE + MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING\n");
 
	MQOPEN(hCon, &odQueue1, optionsQueue1MQOPEN, &hQueue1, &cComplMQOPEN, &cReasonMQOPEN);
	if (cReasonMQOPEN != MQRC_NONE)
	{
			printf("MQOPEN: Reason Code = [%ld]\n", cReasonMQOPEN);
			printf("Reason: [%s]\n", MqReasonToStr(cReasonMQOPEN));
	} // if
	if (cComplMQOPEN == MQCC_FAILED)
	{
		printf("MQOPEN Fehler: Die Queue [%s] kann nicht geöffnet werden\n", odQueue1.ObjectName);
		EndOfPrg(cReasonMQOPEN);
	} // if
	printf("MQOPEN: erfolgreich\n");
 
	system("pause");
 
	// MQGET
	printf("MQGET: Messages werden aus der Queue [%s] gelesen...\n", odQueue1.ObjectName);
 
	gmoMsgGet.Options = MQGMO_NO_SYNCPOINT + MQGMO_FAIL_IF_QUIESCING;
	printf("Optionen: MQGMO_NO_SYNCPOINT + MQGMO_FAIL_IF_QUIESCING\n");
 
	i = 0; // Anzahl gelesenen Messages
	cReasonMQGET = MQRC_NONE;
	while (cReasonMQGET == MQRC_NONE)
	{
		memcpy(mdMsgGet.MsgId, MQMI_NONE, sizeof(mdMsgGet.MsgId));
		memcpy(mdMsgGet.CorrelId, MQCI_NONE, sizeof(mdMsgGet.CorrelId));
 
		datalen = sizeof(bufferMsgGet) - 1;
		MQGET(hCon, hQueue1, &mdMsgGet, &gmoMsgGet, sizeof(bufferMsgGet) - 1, bufferMsgGet, &datalen, &cComplMQGET, &cReasonMQGET);
		printf("MQGET: Reason Code = [%ld]\n", cReasonMQGET);
		if (cReasonMQGET == MQRC_NONE)
		{
			i++;
			if (datalen < sizeof(bufferMsgGet) - 1) bufferMsgGet[datalen] = '\0';
			else bufferMsgGet[sizeof(bufferMsgGet) - 1] = '\0';
 
			printf("MQGET: Message %d = [%s]\n", i, bufferMsgGet);
		} // if
	} // while
 
	system("pause");
 
	// MQPUT
	memset(bufferMsgPut, '\0', sizeof(bufferMsgPut));
	strncpy(bufferMsgPut, MSG1, sizeof(bufferMsgPut) - 1);
	printf("MQPUT: Message [%s] wird in die Queue [%s] geschrieben...\n", bufferMsgPut, odQueue1.ObjectName);
 
	mdMsgPut.MsgType = MQMT_DATAGRAM;
	memcpy(mdMsgPut.Format, MQFMT_STRING, MQ_FORMAT_LENGTH);
	printf("MsgType: MQMT_DATAGRAM\n");
 
	pmoMsgPut.Options = MQPMO_NO_SYNCPOINT + MQPMO_FAIL_IF_QUIESCING;
	printf("Optionen: MQPMO_NO_SYNCPOINT + MQPMO_FAIL_IF_QUIESCING\n");
 
	memcpy(mdMsgPut.MsgId, MQMI_NONE, sizeof(mdMsgPut.MsgId));
	memcpy(mdMsgPut.CorrelId, MQCI_NONE, sizeof(mdMsgPut.CorrelId));
 
	MQPUT(hCon, hQueue1, &mdMsgPut, &pmoMsgPut, strlen(bufferMsgPut), bufferMsgPut, &cComplMQPUT, &cReasonMQPUT);
	if (cReasonMQPUT != MQRC_NONE) printf("MQPUT: Reason Code = [%ld]\n", cReasonMQPUT);
	else printf("MQPUT: erfolgreich\n");
 
	system("pause");
 
	// MQCLOSE
	printf("MQCLOSE: Queue [%s] wird geschlossen...\n", odQueue1.ObjectName);
 
	optionsMQCLOSE = MQCO_NONE;
 
	MQCLOSE(hCon, &hQueue1, optionsMQCLOSE, &cComplMQCLOSE, &cReasonMQCLOSE);
	if (cReasonMQCLOSE != MQRC_NONE) printf("MQCLOSE: Reason Code = [%ld]\n", cReasonMQCLOSE);
	else printf("MQCLOSE: erfolgreich\n");
 
	// MQDISC
	if (cReasonMQCONN != MQRC_ALREADY_CONNECTED)
	{
		printf("MQDISC: Disconnect vom MQM [%s]...\n", qmName);
 
		MQDISC(&hCon, &cComplMQCONN, &cReasonMQCONN);
		if (cReasonMQCONN != MQRC_NONE) printf("MQDISC: Reason Code = [%ld]\n", cReasonMQCONN);
		else printf("MQDISC: erfolgreich\n");
	} // if
 
	printf("==================== END ====================\n");
 
	EndOfPrg(0);
	return 0;
} // main()
 
 
char *MqReasonToStr (MQLONG Reason)
{
	switch (Reason)
	{
		case MQRC_OBJECT_IN_USE: return ("MQRC_OBJECT_IN_USE");
		case MQRC_NOT_AUTHORIZED: return ("MQRC_NOT_AUTHORIZED");
		case MQRC_UNEXPECTED_ERROR: return ("MQRC_UNEXPECTED_ERROR");
		default: return ("Reason Code unbekannt (oder noch nicht implementiert)");
	} // switch (Reason)
} // MqReasonToStr()
 
 
void EndOfPrg (int rc)
{
	system("pause");
	exit(rc);
} // EndOfPrg()
 
// EOF

:!: Redundanz der Variablen für Completion Code und Reason Code ist nicht notwendig.


Stand: 02.03.2012
: Jürgen Kreick

EOF