Asynchronous IPC

Hello,

I need to use asynchronous IPC between client and server. I want to use
MsgDeliverEvent() function to deliver events to client, but this
function needs parameter called rcvid which is returned by MsgReceive,
but if I will use MsgReceive on server side, so server will be blocked.
I don’t want to be server blocked. Can I use MsgDevilerEvent() with
rcvid = 0? I think no, becouse in that case I don’t know to which client
deliver event. What can I do in this situation?
Thanks in advance.

Best regards,

Darius

“Darius” <alpha1@takas.lt> wrote in message news:ckl8uq$1hu$1@inn.qnx.com

Hello,

I need to use asynchronous IPC between client and server. I want to use
MsgDeliverEvent() function to deliver events to client, but this function
needs parameter called rcvid which is returned by MsgReceive, but if I
will use MsgReceive on server side, so server will be blocked. I don’t
want to be server blocked. Can I use MsgDevilerEvent() with rcvid = 0? I
think no, becouse in that case I don’t know to which client deliver event.
What can I do in this situation?

6.3 has a new set of async API.

That being said, a server without MsgReceive is not a server, IMHO.

Thanks in advance.

Best regards,

Darius

Hello,

That being said, a server without MsgReceive is not a server, IMHO.

What do you mean saying “server”? Normal server or resource manager? Can
I use MsgReceive in resource manager? Somehow I think that would be not
good. If I can use MsgReceive in resource manager, so what channel id
should I use? Can I use another connection channel on resource manager
to comunnicate with clients via MsgSend->MsgReceive?

Best regards,
Darius

The resource manger library will to the receive for you. You just need to
attach a pulse handler to your resource manager so that you can service the
pulses.

Regards,

Joe

Darius <alpha1@takas.lt> wrote in message news:ckls3k$gbv$1@inn.qnx.com

Hello,

That being said, a server without MsgReceive is not a server, IMHO.

What do you mean saying “server”? Normal server or resource manager? Can
I use MsgReceive in resource manager? Somehow I think that would be not
good. If I can use MsgReceive in resource manager, so what channel id
should I use? Can I use another connection channel on resource manager
to comunnicate with clients via MsgSend->MsgReceive?

Best regards,
Darius

Darius <alpha1@takas.lt> wrote:

Hello,

That being said, a server without MsgReceive is not a server, IMHO.

What do you mean saying “server”? Normal server or resource manager? Can
I use MsgReceive in resource manager? Somehow I think that would be not
good. If I can use MsgReceive in resource manager, so what channel id
should I use? Can I use another connection channel on resource manager
to comunnicate with clients via MsgSend->MsgReceive?

If you are writing a resource manager, then in any of your handlers for
a message, the ctp->rcvid passed to your handler will be the rcvid you
will later need for delivering a pulse to your client(s).

(The dispatch_block() or resmgr_block() functions actually do a
MsgReceive() as their main blocking point.)

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Hello,

If you are writing a resource manager, then in any of your handlers for
a message, the ctp->rcvid passed to your handler will be the rcvid you
will later need for delivering a pulse to your client(s).

(The dispatch_block() or resmgr_block() functions actually do a
MsgReceive() as their main blocking point.)

Thanks for answering. Think I’m getting the point :slight_smile:

Darius

“Darius” <alpha1@takas.lt> wrote in message news:ckls3k$gbv$1@inn.qnx.com

Hello,

That being said, a server without MsgReceive is not a server, IMHO.

A server usually means a program that will serve client request. In order
for the server to be told what the client wants to do, the server must
listen for incomming request. The “listening” is normaly a block called
under QNX. Listening is perform buy MsgReceive(). If the server is
implemented with the help of the resource manager framework then the details
of MsgReceive are hidden in the resmgr library.

Hence to say that a server doesn’t block doesn’t make much sense. Or course
I’m talking generic implementation of servers.

What do you mean saying “server”? Normal server or resource manager? Can I
use MsgReceive in resource manager? Somehow I think that would be not
good. If I can use MsgReceive in resource manager, so what channel id
should I use? Can I use another connection channel on resource manager to
comunnicate with clients via MsgSend->MsgReceive?

Best regards,
Darius

Hello,

I have encountered some more problems. I have used message_attach()
function to handle my private messges in some range. Question: how to
send a message from client to resource manager that this message will
have desired range value? How do I know is it private message or no? How
to set message range in MsgSend()?

Best regards,
Darius

Darius <alpha1@takas.lt> wrote:

Hello,

I have encountered some more problems. I have used message_attach()
function to handle my private messges in some range. Question: how to
send a message from client to resource manager that this message will
have desired range value? How do I know is it private message or no? How
to set message range in MsgSend()?

All QNX messages start with a header, where the first 16-bit integer
is a “message type”:

struct hdr {
uint16_t type;

}

What you need to do is make sure when your client sends the message,
you use a similar structure, and fill in that “type” field with a
message type in the range registered by your call to message_attach().

This must NOT be in the range of: _IO_MIN (256) to _IO_MAX (511), and
it is recommended that it be > _IO_MAX (511).

So something like:

Server side:

message_attach( dpp, NULL, _IO_MAX+1000, _IO_MAX+2000, func, handle );

Common header:

#define CUSTOM_MSG_TYPE_1 _IO_MAX+1000+5

And client side:

msg.hdr.type = CUSTOM_MSG_TYPE_1
msg.data.blah = whatever;

MsgSend( fd, &msg, sizeof(msg), &replybuf, sizeof(replybuf);

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Hello,

MsgSend( fd, &msg, sizeof(msg), &replybuf, sizeof(replybuf);

What’s fd? I use fd=open("/dev/resmgr/", O_RDWR), but this fd do not
work for MsgSend. The same effect I get when I write any integer number
instead of fd. Then I tried to use ChannelCreate and ConnectAttach, but
resource manager didn’t my message, but client then blocks. In first
case client doesn’t block.

Best regards,
Darius

The Server creates the Channel, and the client connects to it.
If you are not using resource manager then you can use the name_attach() and
name_open() calls to create and connect to the channel.

There is sample client/server code in name_attach() library reference doc.


Regards,

Joe

Darius <alpha_byte@safe-mail.net> wrote in message
news:cl0f6l$icf$1@inn.qnx.com

Hello,

I want to add some addition to my question. Waiting for your answer to the
last question I have tried to do some simple MsgSend() MsgReceive()
client-server application without any resource managers. I have failed > :frowning:
Server didn’t get any message from client. I can’t understand one thing:
client creates channel and attaches a connection, how server would “know”
on
which cannel to wait for a reply? Do I need to use Channel Create on
server?
If so that I will get another chid? How to do in this situation?
I will be thankful for answer to my previous question too.

Best regards,
Darius

Hello,

I want to add some addition to my question. Waiting for your answer to the
last question I have tried to do some simple MsgSend() MsgReceive()
client-server application without any resource managers. I have failed :frowning:
Server didn’t get any message from client. I can’t understand one thing:
client creates channel and attaches a connection, how server would “know” on
which cannel to wait for a reply? Do I need to use Channel Create on server?
If so that I will get another chid? How to do in this situation?
I will be thankful for answer to my previous question too.

Best regards,
Darius

Darius <alpha_byte@safe-mail.net> wrote:

Hello,

I want to add some addition to my question. Waiting for your answer to the
last question I have tried to do some simple MsgSend() MsgReceive()
client-server application without any resource managers. I have failed > :frowning:
Server didn’t get any message from client. I can’t understand one thing:
client creates channel and attaches a connection, how server would “know” on
which cannel to wait for a reply? Do I need to use Channel Create on server?
If so that I will get another chid? How to do in this situation?
I will be thankful for answer to my previous question too.

No, the client does not create a channel.

The server creates a channel.

One or more clients connect to that channel.

The server blocks waiting on the channel it created.

When a client sends a message, the server unblocks, processes the
message, and then replies.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Darius <alpha1@takas.lt> wrote:

Hello,

MsgSend( fd, &msg, sizeof(msg), &replybuf, sizeof(replybuf);

What’s fd? I use fd=open("/dev/resmgr/", O_RDWR), but this fd do not
work for MsgSend. The same effect I get when I write any integer number
instead of fd. Then I tried to use ChannelCreate and ConnectAttach, but
resource manager didn’t my message, but client then blocks. In first
case client doesn’t block.

Without seeing what you are doing, it is very hard to diagnose what
is going wrong.

The core message passing, including MsgSend(fd,…) works. Almost
everything is based on it, including reading and writing files from
disk, creating new processes, etc. If it was broken, you couldn’t
run a program to find out it was broken.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Darius <alpha1@takas.lt> wrote:

Hello,

I need to use asynchronous IPC between client and server. I want to use
MsgDeliverEvent() function to deliver events to client, but this
function needs parameter called rcvid which is returned by MsgReceive,
but if I will use MsgReceive on server side, so server will be blocked.
I don’t want to be server blocked. Can I use MsgDevilerEvent() with
rcvid = 0? I think no, becouse in that case I don’t know to which client
deliver event. What can I do in this situation?
Thanks in advance.

Best regards,

Darius

Tell you what; if you want to pay for postage only (CAD$25) I can airmail you
a slightly damaged “Getting Started with QNX Neutrino” book. This will answer
a large number of your questions…

Cheers,-RK

\

[If replying via email, you’ll need to click on the URL that’s emailed to you
afterwards to forward the email to me – spam filters and all that]
Robert Krten, PDP minicomputer collector http://www.parse.com/~pdp8/

Hello,

Tell you what; if you want to pay for postage only (CAD$25) I can airmail
you
a slightly damaged “Getting Started with QNX Neutrino” book. This will
answer
a large number of your questions…

Thank you for so kind offer. Tomorrow I will ask my boss about that. Hope he
will give me the money. I think this would be much easier for me to do all
this stuff.
Thanks again.

Darius

Hello,

Without seeing what you are doing, it is very hard to diagnose what
is going wrong.

Would you look at the code if I send? If so then I will send tomorrow,
becouse I left all my files at work.

Darius

Darius <alpha1@takas.lt> wrote:

Hello,

Without seeing what you are doing, it is very hard to diagnose what
is going wrong.

Would you look at the code if I send? If so then I will send tomorrow,
becouse I left all my files at work.

Post it here. Don’t email it to me. I won’t look at emailed code,
but if you post it here for comment, I’ll try and take a look at
it.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

Hello,

Post it here. Don’t email it to me. I won’t look at emailed code,
but if you post it here for comment, I’ll try and take a look at
it.

Ok. I’ll try to post my code. This is resource manager’s code:

int io_read(resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb);
int io_message(message_context_t *ctp, int code, unsigned flags, void
*handle);

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;
static char *resursu_buferis;

int main(int argc, char *argv)
{
/
kintamieji kuriuos naudosim */
dispatch_t *dpp;
dispatch_context_t *ctp;
resmgr_attr_t resmgr_attr;
int id, bufdydis, thread_id_driver, coid;
pthread_attr_t driver_attr;
struct sched_param driver_sched, all_sched;
pthread_t dthread;
message_attr_t *msg_attr;

bufdydis = 2048;
resursu_buferis = malloc(bufdydis);

/* sukuriam dispatch interfeisa*/
if((dpp = dispatch_create()) == NULL)
{
printf(“Nepavyko sukurti dispatch interfeiso\n”);
return(EXIT_FAILURE);
}

/* isvalom ir uzpildom resursu menedzerio atributu struktura */
memset(&resmgr_attr, 0, sizeof(resmgr_attr));
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* inicializuojam tam tikru zinuciu handlinimo funkcijas */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
connect_funcs.open = iofunc_open_default;// ar reikia?
io_funcs.read = io_read;

/* inicializuojam musu device’o atributus */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
attr.nbytes = bufdydis;

/* prijungiam musu resursu menedzeri su savo vardu*/
id = resmgr_attach(dpp, &resmgr_attr, “/dev/dario”, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs, &attr);

if(id == -1)
{
printf(“Negalima prijungti resursu menedzerio\n”);
return EXIT_FAILURE;
}

/* aptarnausim savo zinutes /
/
nuo 0x5000 iki 0x5010 */

if(message_attach(dpp, NULL, _IO_MAX+1500, _IO_MAX+2000, &io_message,
NULL) == -1)
{
fprintf(stderr, “Nepavyko priatachinti asmeniniu zinuciu\n”);
return(EXIT_FAILURE);
}


/* inicializuojam dispatch konteksta */
ctp = dispatch_context_alloc(dpp);

/* paleidziam resursu menedzerio amzina cikla */
while(1)
{
if((ctp = dispatch_block(ctp)) == NULL)
{
fprintf(stderr, “bloko klaida\n”);
return EXIT_FAILURE;
}

dispatch_handler(ctp);
}
free(resursu_buferis);
return 0; //sitas niekad nebus vykdomas
}


int io_message(message_context_t *ctp, int code, unsigned flags, void
*handle)
{
printf(“Gavau privacia zinute !!! \n”);
// MsgReply(ctp->rcvid, 1, NULL, 0);

return(0);
}

I deleted io_read code becouse it works fine. The problem is with
private messages. And here is my client code:

int main(int argc, char **argv)
{
int fileid, nuskaityta, chid, coid;
char *buferis;
struct pmy_msg mymsg;

buferis = malloc(100);

fileid = open("/dev/dario", O_RDWR);
if (fileid != -1)
{
nuskaityta = read(fileid, buferis, 100);
printf("%s %d \n", buferis, nuskaityta);

close(fileid);
}
else
{
printf(“Negalejau atidaryti menedzerio, klaida %d\n”, errno);
}

mymsg.type = _IO_MAX+1600;
mymsg.action = MSG_PULSAS;

MsgSend(fileid, &mymsg, sizeof(mymsg), NULL, 0);
printf(“debug \n”);


return(EXIT_SUCCESS);
}

And at last common header for both files:

struct pmy_msg
{
_Uint16t type;
int action;
struct sigevent eventas;
};

So that’s the code. I will be thankfull if you look at it.

Best regards,
Darius

Hello,

Don’t look at my code. I have found my stupid mistake. I have closed fd
just before I used it to MsgSend(). Sorry :slight_smile:

Best regards,
Darius