backgrnd.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:4k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Log:   P:/user/amir/lite/vcs/backgrnd.c_v  $
  3.  * 
  4.  *    Rev 1.8   19 Aug 1997 20:09:16   danig
  5.  * Andray's changes
  6.  * 
  7.  *    Rev 1.7   27 Jul 1997 14:30:12   danig
  8.  * "fl" prefix, flStartEndCriticalSection
  9.  * 
  10.  *    Rev 1.6   07 Jul 1997 15:20:56   amirban
  11.  * Ver 2.0
  12.  * 
  13.  *    Rev 1.5   01 May 1997 12:15:40   amirban
  14.  * Fixed drive switching bug
  15.  * 
  16.  *    Rev 1.4   03 Nov 1996 17:39:58   amirban
  17.  * Call map instead of setMappingContext
  18.  * 
  19.  *    Rev 1.3   29 Aug 1996 14:16:34   amirban
  20.  * Add Win32 option
  21.  * 
  22.  *    Rev 1.2   18 Aug 1996 13:48:54   amirban
  23.  * Comments
  24.  * 
  25.  *    Rev 1.1   12 Aug 1996 15:32:30   amirban
  26.  * Handle drive changes and context saving
  27.  * 
  28.  *    Rev 1.0   31 Jul 1996 14:31:58   amirban
  29.  * Initial revision.
  30.  */
  31. /************************************************************************/
  32. /*                                                                      */
  33. /* FAT-FTL Lite Software Development Kit */
  34. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  35. /* */
  36. /************************************************************************/
  37. #include "flsocket.h"
  38. #include "backgrnd.h"
  39. #ifdef BACKGROUND
  40. #include <setjmp.h>
  41. #include <dos.h>
  42. static void (*backgroundTask)(void *);
  43. typedef struct {
  44.   jmp_buf registers;
  45.   unsigned mappingContext;
  46.   void * object;
  47.   FLSocket * socket;
  48. } Context;
  49. static Context foregroundContext, backgroundContext, *currentContext;
  50. static int switchContext(Context *toContext, int sendValue)
  51. {
  52.   int state;
  53.   if (toContext == currentContext)
  54.     return 0;
  55.   state = setjmp(currentContext->registers); /* save our state */
  56.   if (state == 0) {
  57.     if (backgroundContext.socket) {
  58.       currentContext->mappingContext = flGetMappingContext(backgroundContext.socket);
  59.       if (toContext->mappingContext != UNDEFINED_MAPPING)
  60. flMap(backgroundContext.socket,(CardAddress) toContext->mappingContext << 12);
  61.     }
  62.     currentContext = toContext;
  63.     longjmp(toContext->registers,sendValue);
  64.   }
  65.   /* We are back here when target task suspends, and 'state'
  66.      is the 'sendValue' on suspend */
  67.   return state;
  68. }
  69. int flForeground(int sendValue)
  70. {
  71.   return switchContext(&foregroundContext,sendValue);
  72. }
  73. int flBackground(int sendValue)
  74. {
  75.   return switchContext(&backgroundContext,sendValue);
  76. }
  77. static char backgroundStack[200];
  78. int flStartBackground(unsigned volNo, void (*routine)(void *), void *object)
  79. {
  80.   if (currentContext != &foregroundContext)
  81.     return 0;
  82.   while (backgroundTask) /* already exists */
  83.     flBackground(BG_RESUME); /* run it until it finishes */
  84.   backgroundTask = routine;
  85.   backgroundContext.object = object;
  86.   backgroundContext.socket = flSocketOf(volNo);
  87.   flNeedVcc(backgroundContext.socket);
  88.   return flBackground(BG_RESUME);
  89. }
  90. void flCreateBackground(void)
  91. {
  92.   FLMutex dummyMutex;
  93.   foregroundContext.socket = backgroundContext.socket = NULL;
  94.   if (setjmp(foregroundContext.registers) != 0)
  95.     return;
  96. #ifdef __WIN32__
  97.    _ESP = (void *) (backgroundStack + sizeof backgroundStack);
  98. #else
  99.   flStartCriticalSection(&dummyMutex);
  100.   _SP = FP_OFF((void far *) (backgroundStack + sizeof backgroundStack));
  101.   _SS = FP_SEG((void far *) (backgroundStack + sizeof backgroundStack));
  102.   flEndCriticalSection(&dummyMutex);
  103. #endif
  104.   backgroundTask = NULL;
  105.   if (setjmp(backgroundContext.registers) == 0) {
  106.     currentContext = &foregroundContext;
  107.     longjmp(foregroundContext.registers,1);       /* restore stack and continue */
  108.   }
  109.   /* We are back here with our new stack when 'background' is called */
  110.   for (;;) {
  111.     if (backgroundTask) {
  112.       (*backgroundTask)(backgroundContext.object);
  113.       flDontNeedVcc(backgroundContext.socket);
  114.       backgroundTask = NULL;
  115.     }
  116.     flForeground(-1);
  117.   }
  118. }
  119. #endif