home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d911 / psm.lha / PSM / Source / source.lha / tracking.c < prev    next >
C/C++ Source or Header  |  1993-07-28  |  5KB  |  203 lines

  1.  
  2. #include "psm.h"
  3.  
  4. UBYTE *sem_name = TITLENAME " V" FULL_VERSION " tracking semaphore";
  5.  
  6. struct track_sem {
  7.     struct SignalSemaphore sem;
  8.     struct List track_list;
  9. };
  10.  
  11. struct track_entry {
  12.     struct Node node;
  13.     struct Screen *scrn;
  14.     struct List mem_list;
  15. };
  16.  
  17. struct track_mem {
  18.     struct MinNode node;
  19. };
  20.  
  21. static struct track_sem *get_track_sem(void)
  22. {
  23.     struct track_sem *track;
  24.     
  25.     Forbid();
  26.     if( !(track = (struct track_sem *)FindSemaphore(sem_name)) ) {
  27.         track = (struct track_sem *)
  28.             AllocVec(sizeof(struct track_sem),MEMF_PUBLIC|MEMF_CLEAR);
  29.         if(!track) {
  30.             Permit();
  31.             return NULL;
  32.         }
  33.         if( !(track->sem.ss_Link.ln_Name
  34.                 = AllocVec(strlen(sem_name)+2,MEMF_PUBLIC)) ) {
  35.             Permit();
  36.             FreeVec(track);
  37.             return NULL;
  38.         }
  39.  
  40.         strcpy(track->sem.ss_Link.ln_Name,sem_name);
  41.         track->sem.ss_Link.ln_Pri = 0;
  42.         InitSemaphore(&track->sem);
  43.         NewList(&track->track_list);
  44.         AddSemaphore(&track->sem);
  45.     }
  46.     ObtainSemaphore(&track->sem);
  47.  
  48.     Permit();
  49.     return track;
  50. }
  51.  
  52. // -----------------------------------------------
  53. // Free all memory attached to a screen tracker.
  54. // -----------------------------------------------
  55.  
  56. void FreeScrnTrack(void *scrn_track)
  57. {
  58.     struct Node *ent;
  59.     
  60.     if(!scrn_track) return;
  61.  
  62.     while( (ent=RemTail(&((struct track_entry *)scrn_track)->mem_list)) ) {
  63.         FreeVec(ent);
  64.     }
  65.     
  66.     FreeVec(scrn_track);
  67. }
  68.  
  69. // -----------------------------------------------
  70. // Allocate a new screen tracker.
  71. // -----------------------------------------------
  72.  
  73. void *AllocScrnTrack(void)
  74. {
  75.     struct track_entry *track;
  76.     
  77.     if(!(track=AllocVec(sizeof(struct track_entry),MEMF_PUBLIC|MEMF_CLEAR))) {
  78.         return NULL;
  79.     }
  80.     
  81.     NewList(&track->mem_list);
  82.     track->scrn = NULL;
  83.     return track;
  84. }
  85.  
  86. // -----------------------------------------------
  87. // Allocate a block of memory and attach it to the screen tracker.
  88. // -----------------------------------------------
  89.  
  90. void *AllocScrnTrackMem(void *scrn_track,ULONG size)
  91. {
  92.     void *mem;
  93.  
  94.     size += sizeof(struct track_mem);
  95.  
  96.     mem = AllocVec(size,MEMF_PUBLIC|MEMF_CLEAR);
  97.     
  98.     if(mem) {
  99.         AddTail( &((struct track_entry *)scrn_track)->mem_list, mem );
  100.         return (void *)( ((ULONG)mem) + sizeof(struct track_mem) );
  101.     }
  102.     return NULL;
  103. }
  104.  
  105. // -----------------------------------------------
  106. // Add a completed screen tracker to the public list.
  107. // -----------------------------------------------
  108.  
  109. void AddScrnTrack(void *scrn_track,struct Screen *scrn)
  110. {
  111.     struct track_sem *sem;
  112.  
  113.     if(!scrn_track) return;
  114.  
  115.     if(scrn) {
  116.         ((struct track_entry *)scrn_track)->scrn = scrn;
  117.     } else if(!((struct track_entry *)scrn_track)->scrn) {
  118.         FreeScrnTrack(scrn_track);
  119.         return;
  120.     }
  121.  
  122.     if( (sem = get_track_sem()) ) {
  123.         AddTail(&sem->track_list,scrn_track);
  124.         ReleaseSemaphore(&sem->sem);
  125.     }
  126. }
  127.  
  128. // -----------------------------------------------
  129. // Find and remove the tracker attached to the given screen.
  130. // -----------------------------------------------
  131.  
  132. void *GetScrnTrack(struct Screen *scrn)
  133. {
  134.     struct track_sem *sem;
  135.     struct track_entry *ent;
  136.  
  137.     if(!scrn) return NULL;
  138.  
  139.     if( (sem = get_track_sem()) ) {
  140.         for(ent = head_node(&sem->track_list);
  141.             ent != NULL;
  142.             ent = next_node(ent)) {
  143.             
  144.             if(ent->scrn == scrn) {
  145.                 Remove(&ent->node);
  146.                 ReleaseSemaphore(&sem->sem);
  147.                 return ent;
  148.             }
  149.         }
  150.         ReleaseSemaphore(&sem->sem);
  151.     }
  152.     
  153.     return NULL;
  154. }
  155.  
  156. // -----------------------------------------------
  157. // Check if the given screen is being tracked.
  158. // -----------------------------------------------
  159.  
  160. void *CheckScrnTrack(struct Screen *scrn)
  161. {
  162.     struct track_sem *sem;
  163.     struct track_entry *ent;
  164.  
  165.     if(!scrn) return NULL;
  166.  
  167.     if( (sem = get_track_sem()) ) {
  168.         for(ent = head_node(&sem->track_list);
  169.             ent != NULL;
  170.             ent = next_node(ent)) {
  171.             
  172.             if(ent->scrn == scrn) {
  173.                 ReleaseSemaphore(&sem->sem);
  174.                 return ent;
  175.             }
  176.         }
  177.         ReleaseSemaphore(&sem->sem);
  178.     }
  179.  
  180.     return NULL;
  181. }
  182.  
  183. // -----------------------------------------------
  184. // Close the screen and any memory we may be tracking.
  185. // -----------------------------------------------
  186.  
  187. BOOL CloseScrnTrack(struct Screen *scrn)
  188. {
  189.     struct track_entry *ent;
  190.     
  191.     if(!scrn) return TRUE;
  192.  
  193.     ent = GetScrnTrack(scrn);
  194.     
  195.     if( CloseScreen(scrn) ) {
  196.         if(ent) FreeScrnTrack(ent);
  197.         return TRUE;
  198.     }
  199.  
  200.     AddScrnTrack(ent,NULL);
  201.     return FALSE;
  202. }
  203.