help about MsgReceivev

//============================================
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/dispatch.h>

#define ATTACH_POINT “ser”

/* We specify the header as being at least a pulse */
typedef struct _pulse msg_header_t;

/* Our real data comes after the header */
typedef struct _my_data {
msg_header_t hdr;
int data;
} my_data_t;

/*** Server Side of the code ***/
int server() {
name_attach_t *attach;
my_data_t msg;
int rcvid;

/* Create a global name (/dev/name/global/…) */
if ((attach = name_attach(NULL, ATTACH_POINT, NAME_FLAG_ATTACH_GLOBAL)) == NULL) {
return EXIT_FAILURE;
}

/* Do your MsgReceive’s here now with the chid */
while (1) {
rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);

if (rcvid == -1) {/* Error condition, exit */
break;
}

if (rcvid == 0) {/* Pulse received /
switch (msg.hdr.code) {
case _PULSE_CODE_DISCONNECT:
/

  • A client disconnected all its connections (called
  • name_close() for each name_open() of our name) or
  • terminated
    /
    ConnectDetach(msg.hdr.scoid);
    break;
    case _PULSE_CODE_UNBLOCK:
    /
  • REPLY blocked client wants to unblock (was hit by
  • a signal or timed out). It’s up to you if you
  • reply now or later.
    /
    break;
    default:
    /
  • A pulse sent by one of your processes or a
  • _PULSE_CODE_COIDDEATH or _PULSE_CODE_THREADDEATH
  • from the kernel?
    */
    }
    continue;
    }

/* name_open() sends a connect message, must EOK this */
if (msg.hdr.type == _IO_CONNECT ) {
MsgReply( rcvid, EOK, NULL, 0 );
continue;
}

/* Some other QNX IO message was received; reject it */
if (msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX ) {
MsgError( rcvid, ENOSYS );
continue;
}

/* A message (presumable ours) received, handle */
printf(“Server receive %d \n”, msg.data);
MsgReply(rcvid, EOK, 0, 0);

}

/* Remove the name from the space */
name_detach(attach, 0);

return EXIT_SUCCESS;
}

//============================================

It use ConnectDetach(msg.hdr.scoid) to detach connect.
But now I want to use MsgReceivev to recive message.
It’s define is as follow.

int MsgReceivev( int chid,
const iov_t * riov,
int rparts,
struct _msg_info * info );

It’s message data is iov structure.
How can I find it’s connection ID in this structure??

Thanks.

IOVs are only pointers to actual data areas!

iov_t riov[1];

...


SETIOV(riov[0], &msg, sizeof(msg));

MsgReceivev( ... riov, ...)

-Albrecht

Yes, you are just receiving the message into multiple pieces instead of one contiguous piece of memory. Often this is done to seperate a header from data, etc. as you seem to want to do. If the first part of the iov points to the header, just pick up what you want much as you do currently.

Does it mean, if using name_attach() in IOV message server (e.g. MsgReceivev), the server have to custom one IOV message to emulate _PULSE_CODE_DISCONNECT and call ConnectDetach() to avoid connection upper limit problem as pulse server?

However, I saw that IOV server will not have connection upper limit problem even IOV client call name_close() after name_open() for over 65536 times, where pulse server will.

It appears IOV have no such problem, why?
Moreover, Do I “still” have to custom one of my IOV message to emulate _PULSE_CODE_DISCONNECT and call ConnectDetach()?

For example, IOV message server code:

intChID = ChannelCreate(_NTO_CHF_FIXED_PRIORITY);
ptDpp=_dispatch_create(intChID, 0);
if ((attach = name_attach(ptDpp, "IOV_NAME", 0  )) == NULL) {
   	return 0 ;

}

SETIOV(&riov[0], CmdMode, sizeof(CmdMode));
SETIOV(&riov[1], g_intServerRcv, sizeof(g_intServerRcv));
    ....

while (1) {
	rcvid = MsgReceivev(attach->chid, riov, 2, &info);
                    SETIOV(&siov[1], bytRetInf, 0/*sizeof(bytRetInf)*/);
		pbytData=(uint8_t*)&g_intServerRcv[0];			
		switch (CmdMode) {
		case 0x30:	 // to emulate as _PULSE_CODE_DISCONNECT 
                    ConnectDetach(info.scoid);
    }
    /* below will not being executed by client name_close() call
name_detach(attach, 0);
dispatch_destroy(ptDpp);
ChannelDestroy(intChID);

}


And the IOV client code:

if ( ( fd = name_open("IOV_NAME", 0) ) == -1 )
{
	return 0;
}
    if( MsgSendv(fd,  send_iov, 2, reply_iov, 2 ) == -1 )
    ...
    name_close(fd);

rcvid returned by MsgReceive is what indicated if it’s a message or a pulse. There is no overlap in pulse code and data receive in number. Please read the MsgReceive documentation it’s all well explained.

Of course rcvid can be used to judge messge or pulse.

However, I am talking about an IOV message only server (e.g. no any pulse will be sent to this named channel). For such pure IOV message server, will named channel reach upper limit? Our testing shows NOT which different than pure pulse server, it is quitely strange. Does pure message server still need to call ConnectDetach()?

Sorry don’t understand what you are talking about.