viewer/grphshm.cpp File Reference

#include "mfcpch.h"
#include "evntlst.h"
#include <string.h>
#include "grphics.h"
#include "grphshm.h"

Go to the source code of this file.

Defines

Functions

Variables


Define Documentation

#define EXTERN

Note:
File: grphshm.cpp (Formerly graphshm.c)
Functions for the shared memory sbdaemon connection.
Author:
Ray Smith
Date:
May 24 14:09:38 BST 1990
 * (C) Copyright 1990, Hewlett-Packard Ltd.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.

Definition at line 43 of file grphshm.cpp.


Function Documentation

void cleanup_sbdaemon (  ) 

Forget about the daemon.

Free system resources for when the daemon has failed or been killed.

Definition at line 182 of file grphshm.cpp.

References event_sem, SHMINFO::fds, INFD, NULL, OUTFD, SHMINFO::shmid, shminfo, and SHMINFO::shmstart.

Referenced by kick_daemon(), and start_sbdaemon().

00182                         {  /*forget about the daemon */
00183   #ifdef __MSW32__
00184   if (shminfo.fds[INFD] != NULL) {
00185     CloseHandle (shminfo.fds[INFD]);
00186     shminfo.fds[INFD] = 0;
00187   }
00188   if (shminfo.fds[OUTFD] != NULL) {
00189     CloseHandle (shminfo.fds[OUTFD]);
00190     shminfo.fds[OUTFD] = 0;
00191   }
00192   if (shminfo.shmstart != NULL) {
00193     UnmapViewOfFile (shminfo.shmstart);
00194     shminfo.shmstart = NULL;
00195   }
00196   if (shminfo.shmid != NULL) {
00197     CloseHandle (shminfo.shmid);
00198     shminfo.shmid = NULL;
00199   }
00200   if (event_sem != NULL) {
00201     CloseHandle(event_sem);
00202     event_sem = NULL;
00203   }
00204   #elif defined(__UNIX__)
00205   if (shminfo.fds[INFD] > 0) {
00206     close (shminfo.fds[INFD]);
00207     shminfo.fds[INFD] = 0;
00208   }
00209   if (shminfo.fds[OUTFD] > 0) {
00210     close (shminfo.fds[OUTFD]);
00211     shminfo.fds[OUTFD] = 0;
00212   }
00213   shminfo.shmstart = NULL;
00214   #endif //defined(__UNIX__)
00215 }

DLLSYM void* getshm ( INT32  size  ) 

Get memory.

Get the next element of the shared memory. If there is no more room in the segment, kick the daemon to get it to empty it out and then restart the buffer once it acknowledges the cleanout.

Definition at line 270 of file grphshm.cpp.

References AWAIT_BUFFER, kick_daemon(), NULL, shminfo, SHMINFO::shmsize, SHMINFO::shmstart, and SHMINFO::usedsize.

Referenced by WINFD::Append_text(), WINFD::Arc(), WINFD::Character_height(), WINFD::Clear_view_surface(), WINFD::create(), def_overlap_picture_ops(), def_show_sub_image(), WINFD::Destroy_window(), WINFD::Draw2d(), WINFD::Ellipse(), WINFD::Fill_color(), WINFD::Fill_color_index(), WINFD::Interior_style(), WINFD::Line_color_index(), WINFD::Line_type(), WINFD::Make_picture_current(), WINFD::Marker_color_index(), WINFD::Marker_size(), WINFD::Marker_type(), WINFD::Move2d(), WINFD::Perimeter_color_index(), WINFD::Polygon2d(), WINFD::Polyline2d(), WINFD::Polymarker2d(), WINFD::Re_compute_colourmap(), WINFD::Rectangle(), WINFD::Set_echo(), WINFD::Synchronize_windows(), WINFD::Text2d(), WINFD::Text_alignment(), WINFD::Text_color_index(), WINFD::Text_font_index(), and WINFD::Vdc_extent().

00272                      {
00273   void *segment;                 /*return segment */
00274 
00275   if (shminfo.shmstart == NULL)
00276     return NULL;                 //no daemon connection
00277   size = (size + 3) & ~3;
00278   if (size > shminfo.shmsize)
00279     return NULL;
00280                                  /*too full? */
00281   if (shminfo.usedsize + size > shminfo.shmsize
00282   || shminfo.usedsize < 0) {     /*or read pending */
00283     kick_daemon(AWAIT_BUFFER);  /*get it to read */
00284   }
00285                                  /*address of segment */
00286   segment = (char *) shminfo.shmstart + shminfo.usedsize;
00287   shminfo.usedsize += size;      /*sum used sizes */
00288   return segment;
00289 }

void kick_daemon ( INT8  mode  ) 

Empty queue.

Tell the daemon to read the shared memory and perform all the operations in it. This function blocks until the daemon has emptied the queue.

Function is a NOP on __MAC__

Definition at line 301 of file grphshm.cpp.

References add_event(), AWAIT_BUFFER, cleanup_sbdaemon(), COUNT_READS, ERRCODE::error(), EVENT_HEAD, EVENT_INDEX, EVENTSIZE, EXIT, FALSE, sbdgraphicsevent::fd, SHMINFO::fds, graphicsevent::fildes, FLUSH_IN, INFD, graphicsevent::key, sbdgraphicsevent::key, lock_events(), MAX_PATH, MAX_PENDING, graphicsevent::next, NULL, OUTFD, PIPESIZE, PRIMITIVES, QUEUE_CLEAR, READFAILED, SHMINFO::shmid, shminfo, SHMINFO::shmstart, TRUE, sbdgraphicsevent::type, graphicsevent::type, unlock_events(), SHMINFO::usedsize, WRITEFAILED, graphicsevent::x, sbdgraphicsevent::x, graphicsevent::y, and sbdgraphicsevent::y.

Referenced by def_overlap_picture_ops(), event_reader(), getshm(), and WINFD::Make_picture_current().

00303                   {
00304   #ifndef __MAC__
00305   SBD_GRAPHICS_EVENT event;      /*event from daemon */
00306   GRAPHICS_EVENT real_event;     //converted format
00307   #ifdef __MSW32__
00308   unsigned long nwrite;
00309   unsigned long nread;           //bytes read
00310   char pipe_char[2];             //char from pipe
00311   INT32 pipe_index;              //index to event queue
00312   #endif  //__MSW32__
00313   static INT16 reads_pending = 0;/*acknowledges pending */
00314 
00315   if (mode == COUNT_READS) {
00316     lock_events();
00317     reads_pending--;             /*got a read */
00318     unlock_events();
00319     return;
00320   }
00321   if (shminfo.shmstart == NULL)
00322     return;                      //no connection
00323   if (shminfo.usedsize > 0) {
00324     #ifdef __UNIX__
00325     if (write
00326       (shminfo.fds[OUTFD], (const char *) &shminfo.usedsize,
00327       sizeof (INT32)) != sizeof (INT32))
00328       WRITEFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe");
00329     #else
00330     PRIMITIVES = shminfo.usedsize;
00331     if (WriteFile (shminfo.fds[OUTFD], "xx", 2, &nwrite, NULL) == 0
00332       || nwrite != 2) {
00333       cleanup_sbdaemon();
00334       return;
00335     }
00336    #endif
00337    #ifdef __UNIX__
00338     if (shminfo.shmid < 0) {
00339       if (write (shminfo.fds[OUTFD], (const char *) shminfo.shmstart,
00340         shminfo.usedsize) != shminfo.usedsize)
00341         WRITEFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe");
00342    #else //__UNIX__
00343       if (shminfo.shmid == NULL) {
00344         if (WriteFile (shminfo.fds[OUTFD], (const char *) shminfo.shmstart,
00345           shminfo.usedsize, &nwrite, NULL) == 0
00346          || nwrite != (UINT32) shminfo.usedsize) {
00347           cleanup_sbdaemon();
00348           return;
00349         }
00350    #endif //__UNIX__
00351         shminfo.usedsize = 0;    /*can use it now */
00352       }
00353       else
00354         shminfo.usedsize = -1;   /*need to wait */
00355       lock_events();
00356       reads_pending++;           /*acknowledges due */
00357       unlock_events();
00358     }
00359     if (mode == FLUSH_IN || reads_pending > MAX_PENDING || mode == AWAIT_BUFFER
00360       #ifdef __UNIX__
00361       && shminfo.shmid < 0)
00362       #else //__UNIX__
00363       && shminfo.shmid != NULL)
00364       #endif //__UNIX__
00365     {
00366       while (reads_pending > 0) {
00367       #ifdef __MSW32__
00368         if (event_id == GetCurrentThreadId ()) {
00369           if (ReadFile (shminfo.fds[INFD], pipe_char, 2, &nread, NULL) != 0
00370           && nread == 2) {
00371             pipe_index = EVENT_HEAD;
00372               event = EVENT_INDEX (pipe_index);
00373               pipe_index++;
00374               if (pipe_index >= EVENTSIZE)
00375                 pipe_index = 0;
00376                 EVENT_HEAD = pipe_index;
00377       #endif //__MSW32__
00378       #ifdef __UNIX__
00379                 if (read
00380                   (shminfo.fds[INFD], &event,
00381                   sizeof (SBD_GRAPHICS_EVENT)) !=
00382                   sizeof (SBD_GRAPHICS_EVENT))
00383                   READFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe");
00384       #endif //__UNIX__
00385             if (event.type != QUEUE_CLEAR) {
00386               real_event.fildes = event.fd;
00387                 real_event.type = event.type;
00388                 real_event.key = event.key;
00389                 real_event.x = event.x;
00390                 real_event.y = event.y;
00391                 real_event.next = NULL;
00392                                  /*add event to queue */
00393                 add_event(&real_event);
00394             }
00395             else
00396               reads_pending--;   /*got acknowledge */
00397               #ifdef __MSW32__
00398           }
00399         }
00400         else
00401           Sleep (50);   // a minute? this isn't 1989 :)
00402       #endif //__MSW32__
00403       }
00404       if (shminfo.usedsize < 0)  //must be reentrant
00405           shminfo.usedsize = 0;  /*none used now */
00406     }
00407    #endif // ! __MAC__
00408   }

BOOL8 remote_display ( char *  name  ) 

Check for remote.

Returns TRUE if the DISPLAY environment variable points to a Remote display, and sets the name to the name of the host. Otherwise, returns FALSE.

Definition at line 225 of file grphshm.cpp.

References DISP, FALSE, LOCAL1, LOCAL2, MAX_PATH, NULL, and TRUE.

Referenced by start_sbdaemon().

00227                       {
00228   #if defined (__UNIX__) || defined(__MSW32__)
00229   char *xenv;                    /*DISPLAY environ */
00230   char *nameend;                 //end of name
00231   #ifdef __UNIX__
00232   char thishost[MAX_PATH];       //current host
00233   #endif
00234 
00235   xenv = getenv (DISP);          /*get display variable */
00236   if (xenv != NULL) {
00237     strcpy(name, xenv);
00238     nameend = strchr (name, ':');
00239     if (nameend != NULL)
00240       *nameend = '\0';           /*chop display off */
00241     nameend = strchr (name, '.');
00242     if (nameend != NULL)
00243       *nameend = '\0';           /*chop resolv off */
00244     #ifdef __UNIX__
00245     if (strcmp (name, LOCAL1) && strcmp (name, LOCAL2)
00246     && gethostname (thishost, MAX_PATH) >= 0) {
00247       nameend = strchr (thishost, '.');
00248       if (nameend != NULL)
00249         *nameend = '\0';         /*chop resolv off */
00250       if (strcmp (name, thishost)) {
00251         return TRUE;
00252       }
00253     }
00254     #else
00255     return TRUE;
00256     #endif
00257   }
00258   #endif
00259   return FALSE;
00260 }

void start_sbdaemon (  ) 

Start the daemon.

Creates the shared memory segment and starts up the sbdaemon telling it info about the segment. This only needs to be called once.

It is called automatically from create_window at the first creation attempt.

Definition at line 61 of file grphshm.cpp.

References cleanup_sbdaemon(), DISP, EVENT_HEAD, event_reader(), event_sem, EVENT_TAIL, EVENTSIZE, SHMINFO::fds, INFD, INT32FORMAT, MAX_PATH, NULL, PIPESIZE, remote_display(), REMSH, SBADDR, SBDAEMON, SBDEFAULT, SHMINFO::shmid, shminfo, SHMOFFSET, SHMSIZE, SHMINFO::shmsize, SHMINFO::shmstart, TRUE, SHMINFO::usedsize, USER_RW, WMSHM, and WMSHMDEFAULT.

Referenced by WINFD::create().

00061                       {  /*start the daemon */
00062   #if defined (__UNIX__) || defined(__MSW32__)
00063   char *shmaddr;                 /*address to attach */
00064   char *sbenv;                   /*SB_DISPLAY_ADDR */
00065   INT32 sbaddr;                  /*starbase address */
00066   INT32 wmshm;                   //windows shared mem
00067   char arg1[MAX_PATH];           /*shmid argument */
00068   char arg2[MAX_PATH];           /*shmstart argument */
00069   char arg3[MAX_PATH];           /*shmsize argument */
00070   const char *argv[5];           /*args of sbdaemon */
00071                                  /*for pipe usage */
00072   static char pipebuffer[PIPESIZE];
00073 
00074   sbenv = getenv (SBADDR);       /*get SB_DISPLAY_ADDR */
00075   if (sbenv == NULL || sscanf (sbenv, INT32FORMAT, &sbaddr) != 1)
00076     sbaddr = SBDEFAULT;
00077   shmaddr = getenv (WMSHM);
00078   if (shmaddr == NULL || sscanf (shmaddr, INT32FORMAT, &wmshm) != 1)
00079     wmshm = WMSHMDEFAULT;
00080                                  /*default address */
00081   shmaddr = (char *) sbaddr - (wmshm + SHMSIZE + SHMOFFSET);
00082 
00083   if (!remote_display (arg1)) {
00084     shminfo.shmsize = SHMSIZE;   /*size of segment */
00085     #ifdef __UNIX__
00086     shminfo.shmid = shmget (IPC_PRIVATE, SHMSIZE, USER_RW);
00087     /*get shm segment */
00088     //    if (shminfo.shmid==-1)
00089     //    NO_SHM_SEGMENT.error("start_sbdaemon",ABORT,"Errno=%d",errno);
00090     #ifdef hp9000s800
00091                                  /*attach it */
00092     shminfo.shmstart = shmat (shminfo.shmid, 0, 0);
00093     if ((int) shminfo.shmstart == -1)
00094     #else //hp9000s800
00095                                  /*attach it */
00096       shminfo.shmstart = shmat (shminfo.shmid, shmaddr, 0);
00097     //    if (shminfo.shmstart!=shmaddr)
00098     #endif //hp9000s800
00099     //            SHM_ATTACH_FAILED.error("start_sbdaemon",ABORT,"Errno=%d",errno);
00100     #else //__UNIX__
00101     SECURITY_ATTRIBUTES security;//for handles
00102 
00103     security.nLength = sizeof (security);
00104     security.lpSecurityDescriptor = NULL;
00105                                  //make it inheritable
00106     security.bInheritHandle = TRUE;
00107                                  //anonymous
00108     shminfo.shmid = CreateFileMapping ((HANDLE) 0xffffffff, &security,
00109       PAGE_READWRITE, 0, shminfo.shmsize + 3 * sizeof (INT32)
00110       + EVENTSIZE * sizeof (SBD_GRAPHICS_EVENT), NULL);
00111     if (shminfo.shmid == NULL) {
00112       shminfo.shmstart = NULL;
00113       return;                    //quietly fail
00114     }
00115     shminfo.shmstart =
00116       MapViewOfFile (shminfo.shmid, FILE_MAP_WRITE, 0, 0, 0);
00117     if (shminfo.shmstart == NULL)
00118       return;
00119     EVENT_TAIL = 0;
00120     EVENT_HEAD = 0;
00121     #endif //__UNIX__
00122                                  /*set up args */
00123     sprintf (arg1, "%d", shminfo.shmid);
00124     sprintf (arg2, "%p", shminfo.shmstart);
00125     sprintf (arg3, INT32FORMAT, shminfo.shmsize);
00126     argv[0] = SBDAEMON;          /*set up argv */
00127     argv[1] = arg1;
00128     argv[2] = arg2;
00129     argv[3] = arg3;
00130     argv[4] = NULL;
00131   }
00132   else {
00133     shmaddr = NULL;              //remote
00134     fprintf (stderr, "start_sbdaemon:using %s to connect to machine %s\n",
00135       REMSH, arg1);
00136     #ifdef __UNIX__
00137     shminfo.shmid = -1;
00138     #else //__UNIX__
00139     shminfo.shmid = NULL;
00140     #endif //__UNIX__
00141                                  /*not using shm */
00142     shminfo.shmstart = pipebuffer;
00143     shminfo.shmsize = PIPESIZE;  /*size of pipe buffer */
00144     #ifdef __UNIX__
00145                                  /*command on host */
00146     sprintf (arg2, "%s=0x%x; export %s; %s -1 0 " INT32FORMAT " %s",
00147       SBADDR, sbaddr, SBADDR, SBDAEMON, shminfo.shmsize, getenv (DISP));
00148     #else//__UNIX__
00149                                  /*command on host */
00150     sprintf (arg2, "%s -1 0 %d %s", SBDAEMON, shminfo.shmsize, getenv (DISP));
00151     #endif //__UNIX__
00152     argv[0] = REMSH;             /*set up argv */
00153     argv[1] = arg1;              /*host to use */
00154     argv[2] = arg2;
00155     argv[3] = NULL;
00156   }
00157 
00158   shminfo.usedsize = 0;          /*none used yet */
00159 
00160   #ifdef __UNIX__
00161   //   shminfo.pid=two_way_pipe(argv[0],argv,shminfo.fds);       /*start daemon*/
00162   #else //__UNIX__
00163   if (two_way_pipe (argv[0], argv, shminfo.fds) != 0) {
00164     cleanup_sbdaemon(); 
00165   }
00166   else {
00167                                  //anonymous
00168     event_sem = CreateSemaphore (NULL, 1, 1, NULL);
00169     //xiaofan
00170     _beginthread (event_reader, 0, &shminfo.fds[INFD]);
00171   }
00172   #endif //__UNIX__
00173   #endif //defined (__UNIX__) || defined(__MSW32__)
00174 }


Variable Documentation

EXTERN INT16 maxsbfd = 0

Definition at line 47 of file grphshm.cpp.

Referenced by WINFD::Clear_event_queue(), WINFD::create(), def_overlap_picture_ops(), WINFD::Destroy_window(), and search_event_queue().

EXTERN WINFD sbfds[MAXWINDOWS]

Definition at line 46 of file grphshm.cpp.

Referenced by add_event(), WINFD::Clear_event_queue(), WINFD::create(), def_overlap_picture_ops(), WINFD::Destroy_window(), search_event_queue(), and search_single_queue().

EXTERN SHMINFO shminfo

Definition at line 45 of file grphshm.cpp.

Referenced by cleanup_sbdaemon(), getshm(), kick_daemon(), and start_sbdaemon().


Generated on Wed Feb 28 19:49:27 2007 for Tesseract by  doxygen 1.5.1