mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.6 KiB
169 lines
5.6 KiB
/*
|
|
Enhanced NCSA Mosaic from Spyglass
|
|
"Guitar"
|
|
|
|
Copyright 1994 Spyglass, Inc.
|
|
All Rights Reserved
|
|
|
|
Author(s):
|
|
Jim Seidman [email protected]
|
|
*/
|
|
|
|
#define STATE_ABORT -1 /* Special state sent to abort the current operation */
|
|
#define STATE_INIT 0 /* The first call to a process always uses this state */
|
|
#define STATE_OTHER 1 /* The function can use this state, and
|
|
(STATE_OTHER + n), to track other states
|
|
between STATE_INIT and STATE_DONE */
|
|
|
|
#define STATE_DONE 32767 /* A special return which indicates the function has
|
|
completed and control should be returned to the
|
|
calling function. */
|
|
|
|
/* This is the type of all asynchonous functions. The nState parameter gives
|
|
** the current state of the function (it is always STATE_INIT the first time
|
|
** the function is called). The return value gives the state for the function
|
|
** the next time it is called (or STATE_DONE, in which case the function won't
|
|
** be called again. The value *ppInfo is maintained between calls. On
|
|
** the first call, it points to a GTR_MALLOCed structure containing call
|
|
** parameters (or it is NULL). If *ppInfo != NULL when the function returns
|
|
** STATE_DONE, a GTR_FREE(*ppInfo) is automatically done on the function's
|
|
** behalf.
|
|
*/
|
|
|
|
typedef int (*AsyncFunc)(struct Mwin *mw, int nState, void **ppInfo);
|
|
|
|
/*
|
|
** Type used to identify threads
|
|
*/
|
|
typedef struct ThreadInfo *ThreadID;
|
|
|
|
/* Initialize the async code. This must be done before the first call to
|
|
** Async_StartThread().
|
|
*/
|
|
void Async_Init(void);
|
|
|
|
/* Call the next thread. This is intended to be called in a loop. If the
|
|
** return value is FALSE, that indicates that there are no non-blocked
|
|
** threads right now.
|
|
*/
|
|
BOOL Async_KeepGoing(void);
|
|
|
|
/*
|
|
** This is how one function calls another. afTarget specifies the
|
|
** function to call. pParams must be either NULL or a GTR_MALLOCed
|
|
** structure containing call parameters. This structure should not be
|
|
** freed by the caller.
|
|
**
|
|
** Note that afTarget won't even be called until the calling
|
|
** function returns. After that, the calling function won't be
|
|
** called again until afTarget returns STATE_DONE.
|
|
*/
|
|
|
|
void Async_DoCall(AsyncFunc afTarget, void *pParams);
|
|
|
|
/*
|
|
** This is similar to Async_DoCall(), but whereas Async_DoCall() makes the
|
|
** calling function "block" until afTarget is done, this call starts
|
|
** afTarget as an independent thread. The mw parameter, if not NULL,
|
|
** specifies a window which is associated with the new thread. The return
|
|
** value is an identifier by which the thread can be referenced.
|
|
*/
|
|
|
|
ThreadID Async_StartThread(AsyncFunc afTarget, void *pParams, struct Mwin *mw);
|
|
|
|
/* Return the currently executing thread. This will return NULL if called
|
|
** from within non-threaded code.
|
|
*/
|
|
ThreadID Async_GetCurrentThread(void);
|
|
|
|
/* This function gets the window associated with a given thread. If none,
|
|
** it returns NULL.
|
|
*/
|
|
struct Mwin *Async_GetWindowFromThread(ThreadID ID);
|
|
|
|
/*
|
|
** Terminate the specified thread. If the function that was originally
|
|
** specified in afTarget is blocked waiting on another function, the
|
|
** lowest function will be aborted first (by calling it with STATE_ABORT),
|
|
** and the program will work its way up the tree. Note that if a thread
|
|
** tries to terminate itself it won't actually end until the current
|
|
** function returns.
|
|
*/
|
|
|
|
void Async_TerminateThread(ThreadID ID);
|
|
|
|
/*
|
|
** Terminate all threads associated with a given window.
|
|
*/
|
|
void Async_TerminateByWindow(struct Mwin *mw);
|
|
|
|
/* Terminate all threads in the program. More accurately, set a flag telling
|
|
** the async code to terminate the threads when the current function returns.
|
|
** After terminating the threads, the Async_Init() function will return.
|
|
*/
|
|
void Async_TerminateAllThreads(void);
|
|
|
|
/* Tell the specified thread to stop operation indefinitely. This is useful
|
|
** when there is a system callback which will tell us when to resume.
|
|
*/
|
|
void Async_BlockThread(ThreadID);
|
|
|
|
/* Unblock a thread previously blocked with Async_BlockThread().
|
|
*/
|
|
BOOL Async_UnblockThread(ThreadID);
|
|
|
|
|
|
/*
|
|
** Return true if thread is a valid thread
|
|
*/
|
|
BOOL Async_IsValidThread (ThreadID thread);
|
|
|
|
/*
|
|
** These 2 functions are just like BlockThread and LockThread
|
|
** except that they require a key to authenticate the unlocker.
|
|
**
|
|
** The reason for this is that there are scenarios where asynchronous
|
|
** events need to unblock another thread in a given state, but they have
|
|
** no control over what state that thread is in. For example
|
|
** a thread might be blocked in one of two places, waiting for
|
|
** external input, or blocked on socket i/o. In that case,
|
|
** I don't want to unblock the i/o stuff, but just the code
|
|
** that is looking for my input. The key insures that I only
|
|
** unlock it if it is in the proper mode.
|
|
**
|
|
** Note that the unlock action WILL be lost if the thread is
|
|
** not currently waiting for it.
|
|
**
|
|
** -dpg
|
|
*/
|
|
|
|
typedef int TKey;
|
|
|
|
/* lock/block thread Only the proper key will restart it. */
|
|
void Async_LockThread(ThreadID, TKey key);
|
|
|
|
|
|
/* unlock a thread */
|
|
BOOL Async_UnlockThread(ThreadID, TKey key);
|
|
|
|
/* acquire a unique key */
|
|
TKey Async_GetKey ();
|
|
|
|
|
|
/* Block/unblock all threads associated with a given window
|
|
*/
|
|
void Async_BlockByWindow(struct Mwin *mw);
|
|
|
|
void Async_UnblockByWindow(struct Mwin *mw);
|
|
|
|
BOOL Async_DoThreadsExistByWindow(struct Mwin *mw);
|
|
BOOL Async_DoThreadsExist(void);
|
|
|
|
#ifdef UNIX
|
|
# ifdef FEATURE_TSDI
|
|
void Async_SetVIT (ThreadID id, BOOL i);
|
|
BOOL Async_GetVIT (ThreadID id);
|
|
void Async_SetMyVIT (BOOL i);
|
|
BOOL Async_OkToExit (void);
|
|
# endif /* FEATURE_TSDI */
|
|
#endif /* UNIX */
|