Message-Id: Comments: Authenticated sender is From: "Salvador Eduardo Tropea (SET)" Organization: INTI To: djgpp AT delorie DOT com Date: Mon, 29 Sep 1997 14:57:16 +0000 MIME-Version: 1.0 Content-type: Multipart/Mixed; boundary=Message-Boundary-7620 Subject: Re: DJGPP, interprocess communication, and DPMI CC: michael DOT mauch AT gmx DOT de (Michael Mauch) Precedence: bulk --Message-Boundary-7620 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body That's a reply to various posts on the topic. > wrote: >> Can a DJGPP program running in a DOS box under Windows 95 >> communicate with another currently-running program (either >> another DJGPP program in a different DOS box or a regular >> Win32 app)? I wrote: >> I think one solution could be a real mode TSR loaded before windows. And Eli replied >This might or might not work with Windows 95, because it catches >real-mode interrupts on different levels and not always lets them go >all the way down to your TSR. The Michael TSR was tested under W95, so no problems here. And Michael wrote: >I wrote a quick demo that allows "talking" between DJGPP programs >sitting inside different DOS boxes. You'll have to install a TSR before >you start Win95. The TSR is written in NASM (search for nasm095.zip). >Currently, the "talking" capability is limited to set and retrieve one >word value. To him I'll reply: Bill did it in a better way, you can setup the size of memory used to comunicate the programs and as a plus this memory can be used as a common transfer buffer too. In fact the TSR was for that. Mitchell Spector Experimented the use of the WindOldAp API and found: > I ran it in a DOS box under Windows95, and found that I got >40-50 iterations per second. That's slow, but that's not the >surprising part. The surprising part came when I launched >Rhide, spawned a DOS shell from within Rhide (using the DOS shell >menu item), and found that I got between 700 and 850 iterations per >second! I got in the range of 800 under Win3.1 but in a 486DX4 100!, seems 95 is trully slower. But the slower routine is the one that reports the size, as Eli pointed it can be avoided. But the solution with TSRs is much more faster. The problem is that you must load the TSR, the advantage is that this buffer is shared only by DJGPP applications and hence can be arbitred better than the Lose clipboard. Bill proposed your TB TSR. I tested it and works OK. The idea of sharing the TB is good but I must admit that is a little complex to use the TB for communication between unsyncronized DJGPP applications. Anyways the TSR can be used for one or both purposes. Is easy to communicate only 2 process but for more I think is more complex. Any ideas? I attached source code that works with the Bill's TB TSR, you can type in one box and see the text in other box. SET ------------------------------------ 0 -------------------------------- Visit my home page: http://www.geocities.com/SiliconValley/Vista/6552/ Salvador Eduardo Tropea (SET). (Electronics Engineer) Alternative e-mail: set-sot AT usa DOT net - ICQ: 2951574 Address: Curapaligue 2124, Caseros, 3 de Febrero Buenos Aires, (1678), ARGENTINA TE: +(541) 759 0013 --Message-Boundary-7620 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Text from file 'test.cc' #include #include #include #include #include #include #include #include #include /* for mode definitions */ #include #include #include #include #define __tb_size _go32_info_block.size_of_transfer_buffer #define MAGIC 0x13254687 typedef struct { unsigned len; unsigned segment; } djgpp_tb; int channelOff; void *localCopy; time_t MyID; time_t OtherID; int I_Started=0; typedef struct { int magic; int type; int size; time_t from; time_t to; } Message; #define TO_ALL 0xFFFFFFFF #define TM_REQCON 1 #define TM_GRANTCON 2 #define TM_ASCIICHAR 3 #define TypeM(a) (a->type) int OpenChannel(void) { int fd; djgpp_tb tb_i; __dpmi_regs regs; int tbOff=(__tb_segment<<4)+__tb_offset; fd=open("djgpp tb",O_RDONLY); if (fd<0) return 0; //tb_i.segment=0; //tb_i.len=0; regs.x.cx=0x0006; regs.x.bx=fd; regs.x.ax=0x4402; regs.x.dx=__tb_offset; regs.x.ds=__tb_segment; __dpmi_int(0x21,®s); tb_i.segment=0; dosmemget(tbOff,6,&tb_i); close(fd); printf("tb_i seg :%04x\n",tb_i.segment); printf("tb_i size:%04x\n",tb_i.len); localCopy=malloc(tb_i.len); channelOff=tb_i.segment<<4; return localCopy!=0; } void HandleBroadCast(Message *m) { printf("I got an unexpected broadcast type: %d\n",m->type); } int GetMessage(Message *m, int toAll=0) { int clear=0; dosmemget(channelOff,sizeof(Message),m); // Filter messages from me ;-) and to others if (m->magic==MAGIC && m->from!=MyID && (m->to==MyID || m->to==TO_ALL)) { if (m->size) dosmemget(channelOff+sizeof(Message),m->size,localCopy); // Clearing the magic I indicate the channel is free _dosmemputl(&clear,1,channelOff); if (!toAll && m->to==TO_ALL) { HandleBroadCast(m); return 0; } return 1; } return 0; } void GetMessageWait(Message *m, int toAll=0) { while (!GetMessage(m,toAll)); } int SendMessage(int type, time_t to=0, void *data=0, int size=0) { Message m; // Check if the channel is in use dosmemget(channelOff,sizeof(Message),&m); if (m.magic==MAGIC) return 0; // Ok go ahead m.type=type; m.from=MyID; if (to) m.to=to; else m.to=OtherID; m.magic=MAGIC; m.size=size; dosmemput(&m,sizeof(Message),channelOff); if (data) dosmemput(data,size,channelOff+sizeof(Message)); return 1; } void CleanBuffer(void) { Message m; m.magic=0; dosmemput(&m,sizeof(Message),channelOff); } long timeOut1=18*10; void SendMessageWait(int type, time_t to, void *data=0, int size=0) { long t1=rawclock()+timeOut1; while (!SendMessage(type,to,data,size) && rawclock()=t1) { printf("Time out!"); CleanBuffer(); exit(1); } } int StablishChannel(void) { Message m; MyID=time(0); long t1=rawclock()+timeOut1; // Look if there are other application do { if (GetMessage(&m,1)) { // Yes! if (m.type!=TM_REQCON) { printf("Error other copies are talking\n"); return 0; } OtherID=m.from; SendMessageWait(TM_GRANTCON,OtherID); return 1; } if (rawclock()>=t1) { printf("Time out!"); CleanBuffer(); exit(1); } } while (!SendMessage(TM_REQCON,TO_ALL)); // Nobody so wait for one GetMessageWait(&m); I_Started=1; // Yes! if (m.type!=TM_GRANTCON) { printf("Error other copies are talking\n"); return 0; } OtherID=m.from; return 1; } void SendChar(int c) { SendMessageWait(TM_ASCIICHAR,0,&c,4); } int GetChar(void) { Message m; do { GetMessageWait(&m); } while (m.type!=TM_ASCIICHAR); return *((int *)localCopy); } int main(int argc, char *argv) { printf("tb seg :%04x\n",__tb_segment); printf("tb offs:%04x\n",__tb_offset); printf("tb size:%04x\n",__tb_size); if (!OpenChannel()) { printf("No TSR loaded\n"); return 1; } printf("Waiting for another application\n"); if (!StablishChannel()) return 1; printf("I found a clon! I'm so happy ;-)))\n"); setbuf(stdout,0); int c; if (I_Started) { printf("I born first so I'm the master ]:-), go on, type here\n"); do { c=getch(); SendChar(c); if (c=='\r') putc('\n',stdout); else putc(c,stdout); } while (c!=27); } else { printf("I'm an slave :-(, just look:\n"); do { c=GetChar(); if (c=='\r') putc('\n',stdout); else putc(c,stdout); } while (c!=27); } return 0; } --Message-Boundary-7620--