home *** CD-ROM | disk | FTP | other *** search
-
- #include "psm.h"
-
- UBYTE *sem_name = TITLENAME " V" FULL_VERSION " tracking semaphore";
-
- struct track_sem {
- struct SignalSemaphore sem;
- struct List track_list;
- };
-
- struct track_entry {
- struct Node node;
- struct Screen *scrn;
- struct List mem_list;
- };
-
- struct track_mem {
- struct MinNode node;
- };
-
- static struct track_sem *get_track_sem(void)
- {
- struct track_sem *track;
-
- Forbid();
- if( !(track = (struct track_sem *)FindSemaphore(sem_name)) ) {
- track = (struct track_sem *)
- AllocVec(sizeof(struct track_sem),MEMF_PUBLIC|MEMF_CLEAR);
- if(!track) {
- Permit();
- return NULL;
- }
- if( !(track->sem.ss_Link.ln_Name
- = AllocVec(strlen(sem_name)+2,MEMF_PUBLIC)) ) {
- Permit();
- FreeVec(track);
- return NULL;
- }
-
- strcpy(track->sem.ss_Link.ln_Name,sem_name);
- track->sem.ss_Link.ln_Pri = 0;
- InitSemaphore(&track->sem);
- NewList(&track->track_list);
- AddSemaphore(&track->sem);
- }
- ObtainSemaphore(&track->sem);
-
- Permit();
- return track;
- }
-
- // -----------------------------------------------
- // Free all memory attached to a screen tracker.
- // -----------------------------------------------
-
- void FreeScrnTrack(void *scrn_track)
- {
- struct Node *ent;
-
- if(!scrn_track) return;
-
- while( (ent=RemTail(&((struct track_entry *)scrn_track)->mem_list)) ) {
- FreeVec(ent);
- }
-
- FreeVec(scrn_track);
- }
-
- // -----------------------------------------------
- // Allocate a new screen tracker.
- // -----------------------------------------------
-
- void *AllocScrnTrack(void)
- {
- struct track_entry *track;
-
- if(!(track=AllocVec(sizeof(struct track_entry),MEMF_PUBLIC|MEMF_CLEAR))) {
- return NULL;
- }
-
- NewList(&track->mem_list);
- track->scrn = NULL;
- return track;
- }
-
- // -----------------------------------------------
- // Allocate a block of memory and attach it to the screen tracker.
- // -----------------------------------------------
-
- void *AllocScrnTrackMem(void *scrn_track,ULONG size)
- {
- void *mem;
-
- size += sizeof(struct track_mem);
-
- mem = AllocVec(size,MEMF_PUBLIC|MEMF_CLEAR);
-
- if(mem) {
- AddTail( &((struct track_entry *)scrn_track)->mem_list, mem );
- return (void *)( ((ULONG)mem) + sizeof(struct track_mem) );
- }
- return NULL;
- }
-
- // -----------------------------------------------
- // Add a completed screen tracker to the public list.
- // -----------------------------------------------
-
- void AddScrnTrack(void *scrn_track,struct Screen *scrn)
- {
- struct track_sem *sem;
-
- if(!scrn_track) return;
-
- if(scrn) {
- ((struct track_entry *)scrn_track)->scrn = scrn;
- } else if(!((struct track_entry *)scrn_track)->scrn) {
- FreeScrnTrack(scrn_track);
- return;
- }
-
- if( (sem = get_track_sem()) ) {
- AddTail(&sem->track_list,scrn_track);
- ReleaseSemaphore(&sem->sem);
- }
- }
-
- // -----------------------------------------------
- // Find and remove the tracker attached to the given screen.
- // -----------------------------------------------
-
- void *GetScrnTrack(struct Screen *scrn)
- {
- struct track_sem *sem;
- struct track_entry *ent;
-
- if(!scrn) return NULL;
-
- if( (sem = get_track_sem()) ) {
- for(ent = head_node(&sem->track_list);
- ent != NULL;
- ent = next_node(ent)) {
-
- if(ent->scrn == scrn) {
- Remove(&ent->node);
- ReleaseSemaphore(&sem->sem);
- return ent;
- }
- }
- ReleaseSemaphore(&sem->sem);
- }
-
- return NULL;
- }
-
- // -----------------------------------------------
- // Check if the given screen is being tracked.
- // -----------------------------------------------
-
- void *CheckScrnTrack(struct Screen *scrn)
- {
- struct track_sem *sem;
- struct track_entry *ent;
-
- if(!scrn) return NULL;
-
- if( (sem = get_track_sem()) ) {
- for(ent = head_node(&sem->track_list);
- ent != NULL;
- ent = next_node(ent)) {
-
- if(ent->scrn == scrn) {
- ReleaseSemaphore(&sem->sem);
- return ent;
- }
- }
- ReleaseSemaphore(&sem->sem);
- }
-
- return NULL;
- }
-
- // -----------------------------------------------
- // Close the screen and any memory we may be tracking.
- // -----------------------------------------------
-
- BOOL CloseScrnTrack(struct Screen *scrn)
- {
- struct track_entry *ent;
-
- if(!scrn) return TRUE;
-
- ent = GetScrnTrack(scrn);
-
- if( CloseScreen(scrn) ) {
- if(ent) FreeScrnTrack(ent);
- return TRUE;
- }
-
- AddScrnTrack(ent,NULL);
- return FALSE;
- }
-