1 /* ***********************************************************
  2    *                                                         *
  3    * Copyright, (C) Honeywell Bull Inc., 1987                *
  4    *                                                         *
  5    * Copyright, (C) Honeywell Information Systems Inc., 1986 *
  6    *                                                         *
  7    *********************************************************** */
  8 
  9 /* HISTORY COMMENTS:
 10   1) change(86-06-13,Westcott), approve(87-07-13,MCR7580),
 11      audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 12      Created.
 13   2) change(86-10-04,Flegel), approve(87-07-13,MCR7580),
 14      audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 15      Corrected Q management.
 16   3) change(86-11-24,Flegel), approve(87-07-13,MCR7580),
 17      audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 18      Make sure source is not already sleeping.
 19                                                    END HISTORY COMMENTS */
 20 
 21 /* : PROCEDURE FUNCTION (i_sleep):
 22 
 23 Places the caller's CAT entry onto a queue of entries that are sleeping. The
 24 entry's position on the queue will be in ascending order of the time remaining
 25 until wakeup. The SLEEPING_BIT flag in the CAT will also be set.  A
 26 SET_SLEEP_FLAG minor capability message will be sent to the remote system
 27 indicating the change of status.
 28 */
 29 
 30 /* : RETURNS:
 31 
 32        0, if no error
 33        WSNOTACT, if MOWSE not active
 34        WSINVCAT, if CAT entry not correct
 35 */
 36 
 37 #include <dos.h>
 38 #include <stdio.h>
 39 #include <ws.h>
 40 #include <ws_error.h>
 41 #include <ws_msg.h>
 42 #include <ws_dcls.h>
 43 #include <ws_fgb.h>
 44 #include <cat.h>
 45 #include <wsmincap.h>
 46 
 47 extern int       packet_mode;   /* determines if MOWSE is attached */
 48 extern local_cat *sleepq;       /* pointer to queue of sleeping CATs */
 49 extern local_cat l_CAT[];       /* CAT table for local capabilities */
 50 extern char      mysystem;      /* system id of PC */
 51 
 52 i_sleep (p_sleep_ptr)
 53 struct sleep_struc *p_sleep_ptr;  /* Pointer to the sleep info structure */
 54 {
 55 int  sysid;                 /* system id extracted from param->sender_major */
 56 int  major;                 /* Major index of caller */
 57 unsigned int wtime;         /* time when wakeup will occur */
 58 local_cat *scat1;           /* pointer to queue of sleeping CATs */
 59 local_cat *scat2;           /* pointer to queue of sleeping CATs */
 60 local_cat *mycat;           /* pointer to this caller's CAT */
 61 struct null_msg  sleep_msg; /* message to update remote sleep info */
 62 unsigned int wstime();      /* returns current value of tick counter */
 63 
 64 /* : Return if MOWSE not active */
 65 
 66    if (packet_mode == 0)
 67       return (WSNOTACT);
 68 
 69 /* : Verify that the CAT is in use */
 70 
 71    major = p_sleep_ptr -> source_major - MIN_CAPABILITY_NUMBER;
 72    if ((major < 0) || (major > NUMBER_OF_CAT_ENTRIES))
 73       return (WSINVNUM);
 74 
 75    mycat = &l_CAT[major];
 76    if (mycat -> mcb_ptr  == NULL)
 77       return (WSINVMCB);
 78 
 79 /* : Make sure caller is not already sleeping */
 80 
 81    if (mycat -> flags & SLEEPING_BIT)
 82       return (WSSLPING);
 83 
 84    mycat -> flags |= SLEEPING_BIT;
 85 
 86 /* : Insert the information into the sleep queue */
 87 
 88    wtime = p_sleep_ptr -> time;
 89    wtime += wstime();
 90    mycat -> flags |= SLEEPING_BIT;
 91    mycat -> sleep_time = wtime;
 92 
 93 /* : - If queue is empty insert at top */
 94 
 95    if (sleepq == NULL)
 96    {  sleepq = mycat;
 97       mycat -> next_cat = NULL;
 98    }
 99 
100 /* : - Head of list */
101 
102    else if (sleepq -> sleep_time > wtime)
103    {  mycat -> next_cat = sleepq;
104       sleepq = mycat;
105    }
106 
107 /* : Elsewhere in list */
108 
109    else for (scat1 = sleepq, scat2 = NULL; scat1 != NULL;)
110    {  if (scat1 -> sleep_time > wtime)             /* Middle */
111       {  mycat -> next_cat = scat1;
112          scat2 -> next_cat = mycat;
113          scat1 = NULL;
114       }
115 
116       else if (scat1 -> next_cat == NULL)          /* Tail */
117       {  scat1 -> next_cat = mycat;
118          scat1 = NULL;
119       }
120 
121       else                                         /* Elsewhere */
122       {  scat2 = scat1;
123          scat1 = scat2 -> next_cat;
124       }
125    }
126 
127 /* : Send message to remote system to set sleep flag */
128 
129    sleep_msg.system = WSMULTICS;
130    sleep_msg.major  = WSMAJCAP;
131    sleep_msg.minor  = WS_SET_SLEEP_FLAG;
132    sleep_msg.source_major = p_sleep_ptr -> source_major;
133    sleep_msg.source_system = mysystem;
134    return (send_i_mess(&sleep_msg, sizeof(struct null_msg)-1, NULL, 0));
135 }
136 ^Z