[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference bulova::decwindows

Title:DECWINDOWS
Notice:DECwindows Motif V1.2-4 SSB kits: note 5519
Moderator:GRIM::MESSENGER
Created:Wed Nov 28 1990
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:5861
Total number of notes:24081

5782.0. "Virtual size of image increases continuousely ?" by TAV02::ZVI_P (Here we are) Tue Feb 25 1997 08:29

Hi

 A customer problem.

 An applicatio that uses some X calls is consumming virtual memory.

 When they run the image they see that the amount of "Virtual pages"
 increases in burtsts and thus page file free space decreases. 

 As this application is a GUI for some process control, after enough time
 the pagefile is consumed and the machine is stuck.

 This seems to me memory leak. 
 
 The application actually watches the mouse and responds to mouse clicks.
 One would expect that after a while the virtual size of the image will
 stabilize.

 We did some elementary tests and commented out some statements. 
 We suspect that the problem occurs when the call XGrabPointer is in the
 code. 
 
 Is this a known problem ? Is there a solution ?

 -.1 contains the source of the program.

		Thanks
		Zvi
T.RTitleUserPersonal
Name
DateLines
5782.1The programTAV02::ZVI_PHere we areTue Feb 25 1997 08:39585
Here is the program.
It uses a mailbox to communicate with another process. I assume this part
of the program is not the cause of the virtual memory leak.


/*
  	File name           : 51XXTERM11.C
*/

/*---------------------- XWindows --------------------------------------------*/
#include <Xlib.h>
#include <Xutil.h>
/*---------------------- C IO ------------------------------------------------*/
#include <stdio.h>
#include <iodef.h>
#include <ssdef.h>
#include <descrip.h>
/*---------------------- Private ---------------------------------------------*/
#include "51XXTerm11.h"

#define DECTERM_WMNAME "51XXTerm1"
#define RETRIES        3
/*----------------------------------------------------------------------------*/
char		mice_buffer[6];
unsigned int	mbx_buffer[3];
int		mice_counter;
short		mice_channel;
short		mbx_channel;
short		mbx_channel_a;

IO_STATUS	mice_status;
IO_STATUS	mbx_status;
IO_STATUS	mbxa_status;

Display		*display;
Cursor		cursor;
Window		root = 0,
		term = 0,
		parent,
 		child,
		focus;
XWindowAttributes
		xwa;
unsigned long	mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
MICE		mice;

int		any_rc;
unsigned        event_flag_LAT;
unsigned        event_flag_MBX;
unsigned        event_alarm_MBX;
unsigned        event_flag_timer;
$DESCRIPTOR(  t_str,  "0 ::.01"/* string for SYS$BINTIM for 10 msec */ );
unsigned long t_pause[2]; /* quadword for time in internal format */

mouse_interrupt()
{
  short          is_short;
  unsigned char	 *to_char;
  int 		 state;
  int		 io_rc;
 
  while ( 1 ) /* added for use break */
  {
    /* only if mouse init was send */
    if( !mice.send )
      break;

    /* move only if on screen */
    XGetInputFocus( display, &focus, &state ); 

    if( focus != term )  
    {
      if ( mice.grab ) 
        XSetInputFocus( display, term, RevertToParent, CurrentTime );
      else  
        break; 
    }    

    XQueryPointer( display, term, &parent, &child, 
                   &mice.abs_x, &mice.abs_y, &mice.x, &mice.y,
                   &mice.buttons );
    if (!mice.grab )
    {
      mice.x -= mice.x_offset;			/* Adjust mice response area */
      mice.y -= mice.y_offset;
      if( mice.x < 1 || mice.x > mice.area_width ||
          mice.y < 1 || mice.y > mice.area_height )
        break;
    }
    if ( mice.x == mice.previous_x &&
         mice.y == mice.previous_y &&
         mice.buttons == mice.previous_buttons )
      break;

    mice_buffer[0] = (unsigned char)0x87;		/* 10000111 */
    if( mice.buttons & Button1Mask )
      mice_buffer[0] &= (unsigned char)0x83;		/* 10000011 */
    if( mice.buttons & Button2Mask )
      mice_buffer[0] &= (unsigned char)0x85;		/* 10000101 */
    if( mice.buttons & Button3Mask )
      mice_buffer[0] &= (unsigned char)0x86;		/* 10000110 */

    is_short = (short)mice.x;
    to_char = &is_short;
    mice_buffer[2] = *to_char++;
    mice_buffer[1] = *to_char;

    is_short = (short)mice.y;
    to_char = &is_short;
    mice_buffer[4] = *to_char++;
    mice_buffer[3] = *to_char;

    mice.previous_x = mice.x;
    mice.previous_y = mice.y;
    mice.previous_buttons = mice.buttons;

    if( ( ( io_rc = SYS$QIOW( event_flag_LAT, mice_channel,
                              IO$_WRITEPBLK | IO$M_NOFORMAT,
                              &mice_status, 0, 0,
                              mice_buffer, 5, 0, 0, 0, 0 ) ) != SS$_NORMAL ) ||
                             ( mice_status.condition != SS$_NORMAL ) )
    {
      printf("Error after: %s in main, status %d, iosb %d\n",
              "SYS$QIOW", io_rc, mice_status.condition );
      if ( connect_lat() )
        go_out(); 
      else
      {
        if( ( ( io_rc = SYS$QIOW( event_flag_LAT, mice_channel,
                                  IO$_WRITEPBLK | IO$M_NOFORMAT,
                                  &mice_status, 0, 0,
                                  mice_buffer, 5, 0, 0, 0, 0 ) ) != SS$_NORMAL )
                                  || ( mice_status.condition != SS$_NORMAL ) ) 
        {                               
          printf("Error after: %s in main, status %d, iosb %d\n",
                  "SYS$QIOW", io_rc, mice_status.condition );
          go_out();
        }
      }
    }
    break;
  }

  /* set AST for read mouse coordinates and clicks every 10 msec */
  SYS$SETIMR ( event_flag_timer, &t_pause[0], mouse_interrupt, 0, 0 ); 
}


/*----------------------------------------------------------------------*\
|* Main subroutine.							*|
\*----------------------------------------------------------------------*/
main()
{          
  SYS$BINTIM ( &t_str, &t_pause[0] ); /* build the quadword time */

  /* get event flag for LAT_port */
  if (any_rc = LIB$GET_EF( &event_flag_LAT) != SS$_NORMAL )
  {
    printf( "Error after: %s in main, status %d\n", "LIB$GET_EF for LAT", any_rc );
    send_alarm();
    exit( any_rc );
  }
  /* get event flag for main MBX */
  if( any_rc = LIB$GET_EF( &event_flag_MBX) != SS$_NORMAL )
  {
    printf( "Error after: %s in main, status %d\n", "LIB$GET_EF for MBX", any_rc );
    LIB$FREE_EF( &event_flag_LAT );
    send_alarm();
    exit( any_rc );
  }
  /* get event flag for alarm MBX */
  if( any_rc = LIB$GET_EF( &event_alarm_MBX) != SS$_NORMAL )
  {
    printf( "Error after: %s in main, status %d\n", "LIB$GET_EF for alarm MBX", any_rc );
    LIB$FREE_EF( &event_flag_LAT );
    LIB$FREE_EF( &event_flag_MBX );
    send_alarm();
    exit( any_rc );
  }
  /* get event flag for timer */
  if( any_rc = LIB$GET_EF( &event_flag_timer) != SS$_NORMAL )
  {
    printf( "Error after: %s in main, status %d\n", "LIB$GET_EF for timer", any_rc );
    LIB$FREE_EF( &event_flag_LAT );
    LIB$FREE_EF( &event_flag_LAT );
    LIB$FREE_EF( &event_alarm_MBX );
    send_alarm();
    exit( any_rc );
  }
  if( open_mail() )
    go_out();
  if( open_channel() )
    go_out();
  if( open_display() )
    go_out();

/* set AST for read mouse coordinates and clicks every 10 msec */
  SYS$SETIMR ( event_flag_timer, &t_pause[0], mouse_interrupt, 0, 0 ); 


  mlisten();
  /* if mlisten finished -> stop */

  LIB$FREE_EF( &event_flag_timer );
  close_display();
  go_out();
}


go_out()
{

  SYS$QIOW(event_flag_LAT, mice_channel, IO$_TTY_PORT | IO$M_LT_DISCON,
           &mice_status, 0, 0, 0, 0, 0, 0, 0, 0);
  SYS$DASSGN( mice_channel );
  
  any_rc = LIB$FREE_EF( &event_flag_LAT );
  any_rc = LIB$FREE_EF( &event_flag_MBX );
  any_rc = LIB$FREE_EF( &event_alarm_MBX );
  send_alarm();
  exit( 0 );
}

send_alarm()
{
int alarm;

  alarm = 1;
  SYS$QIOW( event_alarm_MBX, mbx_channel_a, 
           IO$_WRITEVBLK | IO$M_NOW | IO$M_NORSWAIT,
           &mbxa_status, 0, 0, 
           &alarm, 4, 0, 0, 0, 0);
}

/*======================================================================*\
|*================ Subroutines =========================================*|
\*======================================================================*/
/*----------------------------------------------------------------------*\
|* open_mail subroutine: establish connection with the mail box.	*|
\*----------------------------------------------------------------------*/
open_mail()
{
  int	io_rc;
  $DESCRIPTOR(  mbx, "51XXMOUSE$MBX" );
  $DESCRIPTOR(  mbx_a, "51XXMOUSE_A$MBX" );

  if( ( io_rc = SYS$CREMBX( 0, &mbx_channel, 12, 120, 0, 0, &mbx ) ) != SS$_NORMAL )
  {
    printf( "Error after: %s in open_mail, status %d\n", "SYS$CREMBX", io_rc );
    return( 1 );
  }

  if( ( io_rc = SYS$CREMBX( 0, &mbx_channel_a, 4, 40, 0, 0, &mbx_a ) ) != SS$_NORMAL )
  {
    printf( "Error after: %s in open_mail, status %d\n", "SYS$CREMBX", io_rc );
    return( 1 );
  }

  return ( 0 );
}

/*----------------------------------------------------------------------*\
|* mlisten subroutine: receive change mouse status command		*|
|*	from the parent process.					*|
\*----------------------------------------------------------------------*/
void mlisten()
{
  char dummy;
  int io_rc;
  int mice_xx, mice_yy;  /* this x,y coordinates for move_mouse only */
  int state, i;
  unsigned short
                is_short;
  unsigned char	*to_char;

  while ( 1 )
  {
    if( ( io_rc = SYS$QIOW( event_flag_MBX, mbx_channel, IO$_READVBLK, &mbx_status,
                            0, 0, mbx_buffer, 12, 0, 0, 0, 0 ) != SS$_NORMAL ) ||
        ( mbx_status.condition != SS$_NORMAL ) ||
        ( mbx_status.count != 12 ) ) 
    {
      printf( "Error after: %s in mlisten, status %d, iosb %d, buffer size %d\n",
              "SYS$QIOW", io_rc, mbx_status.condition, mbx_status.count );
      return;
    }
    /* all mouse function activates only if in focus */
    XGetInputFocus( display, &focus, &state );
    if( focus != term ) /* if not in focus then set the mouse to focus */
      XSetInputFocus( display, term, RevertToParent, CurrentTime );

    switch( mbx_buffer[0] )
    {
      case INIT_MOUSE:
        XWarpPointer( display, None, term, 0, 0, 0, 0,
                      mice.x_offset, mice.y_offset );
        mice.send = 1;
        break;
      case GRAB_MOUSE:
        if( mice.send && !mice.grab )
        {
          XDefineCursor( display, term, cursor );
          XGrabPointer ( display, term, 0, mask, GrabModeAsync, GrabModeAsync,
                                  term, cursor, CurrentTime );
          mice.grab = 1;
        }
        break;
      case FREE_MOUSE:
        if( mice.send && mice.grab )
        {
          XUndefineCursor( display, term );
          XUngrabPointer( display, CurrentTime );
          mice.grab = 0;
        }
        break;
      case MOVE_MOUSE:
        if( mice.send )
        {
          mice_xx = mbx_buffer[1];
          mice_yy = mbx_buffer[2]; 
          if ( !mice.grab )
            XGrabPointer( display, term, 1, mask, GrabModeAsync, GrabModeAsync,
                          None, None, CurrentTime );
          XWarpPointer( display, None,term /* term*/, 0, 0, 0, 0,
                        mice_xx, mice_yy );
          if ( !mice.grab )
            XUngrabPointer( display, CurrentTime );
        }
        break;
    }
  }

  return;
}

/*----------------------------------------------------------------------*\
|* open_channel subroutine: assign the channel for the mouse output.	*|
\*----------------------------------------------------------------------*/
open_channel()
{
  int	io_rc;
  $DESCRIPTOR( port, "51XXMOUSE$PORT" );

  if( ( io_rc = SYS$ASSIGN( &port, &mice_channel, 0, 0 ) ) != SS$_NORMAL )
  {
    printf( "Error after: %s in open_channel, status %d\n", "SYS$ASSIGN", io_rc );
    return( 1 );
  }

  /* In order to allow hangup notification, enable CTRL/Y AST    */
  /* delivery for the LTAxxx: device. The CTRL/Y AST is called   */
  /* if an abnormal termination occurs to the remote application */
  /* device                                                      */

  if( ( ( io_rc = SYS$QIOW( event_flag_LAT, mice_channel, IO$_SETMODE | IO$M_CTRLYAST,
                            &mice_status, 0, 0,
                            ts_hangup, 0, 3 /* user mode */, 0, 0, 0 ) ) != SS$_NORMAL ) ||
      ( mice_status.condition != SS$_NORMAL ) )
  {
    printf( "Error after: %s in open_channel, status %d, iosb %d\n",
            "SYS$QIOW (mode)", io_rc, mice_status.condition );
    return( 1 );
  }

  if ( connect_lat() )
    return ( 1 );
  else
    return ( 0 );
}

/*----------------------------------------------------------------------*\
|* connect_lat subroutine: connect to LAT port.		            	*|
\*----------------------------------------------------------------------*/
connect_lat(void) 
{
 int i,io_rc;
 static float	pause = 0.5;
 
  /* solicit the connection to the LT device */
  for ( i=0; i<RETRIES; i++)
  {
     SYS$QIOW(event_flag_LAT, mice_channel, IO$_TTY_PORT | IO$M_LT_DISCON,
              &mice_status, 0, 0, 0, 0, 0, 0, 0, 0);

     if( (( io_rc = SYS$QIOW( event_flag_LAT, mice_channel,
                              IO$_TTY_PORT | IO$M_LT_CONNECT,
                              &mice_status, 0, 0,
                              0, 0, 0, 0, 0, 0 ) ) != SS$_NORMAL ) ||
         ( mice_status.condition != SS$_NORMAL ) )
     {
        printf("Error after: %s in connect_lat, status %d, iosb %d, rejection %d (pg 8-58)\n",
               "SYS$QIOW (connect)", io_rc, mice_status.condition,
                                            mice_status.count );
        LIB$WAIT( &pause );
     }     
     else
       return ( 0 ) ;
  }

  return ( 1 );
}

/*----------------------------------------------------------------------*\
|* ts_hungup subroutine: handle T.S disconnections              	*|
\*----------------------------------------------------------------------*/
void ts_hangup(void) 
{
   printf("Hungup Error, trying to reconnect\n");
   if ( connect_lat() )
    go_out();
   return;
}


/*----------------------------------------------------------------------*\
|* open_display subroutine: initialize Xwindow & find terminal window 	*|
|* 	properties							*|
\*----------------------------------------------------------------------*/
open_display()
{

  float	pause = 3.0;
  int i; 
  unsigned int cursor_width,
               cursor_height;
  char cursor_bits[] = 
  {
    0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };
  Pixmap cursor_shape;
  XColor cursor_fore,
         cursor_back;

  display = XOpenDisplay( 0 );
  if( !display )
  {
    printf( "Could not open display\n" );
    return( 1 );
  }
  root = XRootWindow( display, DefaultScreen( display ) );

  memset( (char *)&cursor_fore, 0x00, sizeof( XColor ) );
  memset( (char *)&cursor_back, 0x00, sizeof( XColor ) );
  
  cursor_shape = XCreatePixmapFromBitmapData( display, root, cursor_bits, 16, 16, 1, 0, 1 );
  XQueryBestCursor( display, root, 16, 16, 
                    &cursor_width, &cursor_height );
  cursor = XCreatePixmapCursor( display, cursor_shape, cursor_shape,
                                &cursor_fore, &cursor_back, 0, 0 );

  term = fetch_window( display, root );
  if( term == NULL )
  {
    printf( "Could not fetch DECTerm window trying again\n" );
    return( 1 );
  }
  XGetWindowAttributes( display, term, &xwa );

  memset( mice_buffer, 0, sizeof( mice_buffer ) );
  mice.send = 0;
  mice.grab = 0;
  mice.x_offset = xwa.width / WINDOW_COLUMNS;
  mice.y_offset = ( xwa.height - Y_OFFSET ) / WINDOW_LINES;
  mice.area_width = mice.x_offset * AREA_COLUMNS;
  mice.area_height = mice.y_offset * AREA_LINES;
  mice.x_offset += X_OFFSET;
  mice.y_offset += Y_OFFSET;

  return( 0 );
}

/*----------------------------------------------------------------------*\
|* close_display subroutine: end window activity.			*| 
\*----------------------------------------------------------------------*/
void close_display()
{
  if (mice.grab)
  {
    XUndefineCursor( display, term );
    XUngrabPointer ( display, CurrentTime );
    mice.grab = 0;
  }
  mice.send = 0;
  XFreeCursor( display, cursor );
  XCloseDisplay( display );    

  return;
}

/*----------------------------------------------------------------------*\
|* fetch_window subroutine: fetch DECTerm window ID.			*|
|*	To do this look for window in the center of the screen.		*|
\*----------------------------------------------------------------------*/
Window fetch_window( display, top )
  Display	*display;
  Window	top;
{
  Window	*w[10];
  int		i, x, y, jx, jy;

  XGetWindowAttributes( display, top, &xwa );
  x = xwa.width / 2;
  y = xwa.height / 2;
  XTranslateCoordinates( display, top, top, x, y, &jx, &jy, &w[0] );

  for( i = 0; i < 9 && w[i] > 0; ++i )
    XTranslateCoordinates( display, top, w[i], x, y, &jx, &jy, &w[i + 1] );
  return( w[i - 1] );
}


The private header file:


/*

  	File name           : 51XXTERM11.H
  	Programer name      : Anatoly Lerman
  	Writen date	    : 26/04/94
  	last update         :
  	external tasks	    :
   	external subroutine :
  	file description    : This file is the header file for the
                              51XXTERM11.C file.

*/
/*----------------------------------------------------------------------------*/
#define		PAUSE		0.010

#define		WINDOW_LINES	28
#define		WINDOW_COLUMNS	82
#define		AREA_LINES	24
#define		AREA_COLUMNS	80
#define		X_OFFSET	3
#define		Y_OFFSET	7

#define		MONITOR_X	512
#define		MONITOR_Y	480

#define 	OPEN_WINDOW	1
#define 	CLOSE_WINDOW	2
#define 	MOVE_WINDOW	3
#define 	ACTIVATE_WINDOW	4
#define 	SET_CURSOR	5
#define 	CLEAR_WINDOW	6
#define 	INIT_MOUSE	7
#define 	GRAB_MOUSE	8
#define 	FREE_MOUSE	9
#define		RESET_DISPLAY	10
#define 	STOP_MOUSE	11
#define 	MOVE_MOUSE	15

#define 	TRUE		1
#define 	FALSE		0

/*----------------------------------------------------------------------------*/
typedef struct
{
  short		condition;
  short		count;
  int		info;
}		IO_STATUS;

typedef struct
{
  int		abs_x, abs_y,
		x, y, previous_x, previous_y;
  unsigned int	buttons, previous_buttons;
  unsigned char	send;
  unsigned char	grab;
  unsigned int	area_width,
		area_height,
		x_offset,
		y_offset;
}		MICE;

/*----------------------------------------------------------------------------*/
void		close_display();
void		mlisten();
Window 		fetch_window();
int	        connect_lat(void);
void            ts_hangup(void);
5782.2GRIM::MESSENGERBob MessengerTue Feb 25 1997 16:176
I don't know of any memory leaks in XGrabPointer.   It just sends a
request to the server and waits for a reply.  There might be a memory leak
in the server if you did a lot of grabs without doing ungrabs, but this
shouldn't affect the client process.

				-- Bob