home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / admct / admcclos.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  10KB  |  315 lines

  1. /********************* START OF SPECIFICATIONS *********************
  2. *
  3. * SUBROU1TINE NAME:  MCICLOS.C
  4. *
  5. * DESCRIPTIVE NAME: Close Waveform Device.
  6. *
  7. *
  8. *
  9. *              Copyright (c) IBM Corporation  1991, 1993
  10. *                        All Rights Reserved
  11. *
  12. * FUNCTION:  A streaming MCD should do the following on a close.
  13. *
  14. *  A. Stop all commands which are active on another thread(s).
  15. *  B. Destroy all active streams.
  16. *  C. Close all open files.
  17. *  D. Delete any temporary files.
  18. *  E. Close any connected devices (such as an amp-mixer).
  19. *  F. If MCI_NOTIFY was used, notify the caller of completion.
  20. *
  21. * NOTES: When The Process is killed all threads Die.  Thus
  22. *        we check if the MCI_CLOSE_EXIT flag is passed in.  If this
  23. *        flag is passed, then will NOT do a stop before destroying
  24. *        the stream.   A stop in this scenario will cause a hang since
  25. *        the streaming subsystem has lost necessary threads.
  26. *
  27. * ENTRY POINTS:
  28. *
  29. * INPUT: MCI_CLOSE message.
  30. *
  31. * EXIT-NORMAL: Instance deleted, Device released.
  32. *
  33. * EXIT_ERROR:  Error Code.
  34. *
  35. * EFFECTS: None.
  36. *
  37. * INTERNAL REFERENCES: PostMDMMessage(), DestroyStream().
  38. *
  39. * EXTERNAL REFERENCES: SpiDestroyStream ()    - SSM SPI.
  40. *                      mdmDriverNotify  ()    - MDM API.
  41. *                      mciSendCommand   ()    - MDM API.
  42. *                      mciConnection    ()    - MDM API.
  43. *                      mmioClose        ()    - MMIO API.
  44. *                      HhpFreeMem       ()    - Heap Manager.
  45. *                      DosCloseEventSem ()    - OS/2 API.
  46. *                      DosCloseMutexSem ()    - OS/2 API.
  47. *                      DosFreeModule    ()    - OS/2 API.
  48. *
  49. *********************** END OF SPECIFICATIONS **********************/
  50.  
  51. #define INCL_BASE
  52. #define INCL_DOSMODULEMGR
  53. #define INCL_DOSSEMAPHORES
  54.  
  55. #include <os2.h>                        // OS2 defines.
  56. #include <string.h>
  57. #include <os2medef.h>                   // MME includes files.
  58. #include <stdlib.h>                     // Math functions
  59. #include <ssm.h>                        // SSM Spi includes.
  60. #include <meerror.h>                    // MM Error Messages.
  61. #include <mmioos2.h>                    // MMIO Include.
  62. #include <mcios2.h>                     // MM System Include.
  63. #include <mcipriv.h>                    // MCI Connection stuff
  64. #include <mmdrvos2.h>                   // MCI Driver include.
  65. #include <mcd.h>                        // AudioIFDriverInterface.
  66. #include <hhpheap.h>                    // Heap Manager Definitions
  67. #include <qos.h>
  68. #include <audiomcd.h>                   // Component Definitions.
  69. #include "admcfunc.h"                   // Function Prototypes.
  70.  
  71. RC MCIClos (FUNCTION_PARM_BLOCK *pFuncBlock)
  72. {
  73.   ULONG               ulrc;           // RC
  74.   ULONG               ulParam1;       // Incoming MCI Flags
  75.   ULONG               ulAbortNotify = FALSE; // whether to abort play/record operation
  76. //  ULONG               ulCount;
  77.   INSTANCE            *ulpInstance;   // Active Instance
  78.   ULONG               ulCloseFlags;   // Mask for MCI Flags
  79.  
  80.   MTIME_EVCB           *pCuePoint;
  81.   MTIME_EVCB           *pTempCuePoint;
  82.  
  83.   extern     HID     hidBTarget;  /* Stream handler to install to */
  84.  
  85.   /*******************************************
  86.   * Dererence Pointers From Thread Block
  87.   ********************************************/
  88.  
  89.   ulParam1 =   pFuncBlock->ulParam1;
  90.   ulpInstance = (INSTANCE *)pFuncBlock->ulpInstance;
  91.  
  92.   /***************************
  93.   * Intialize Variables
  94.   ***************************/
  95.   ulCloseFlags = ulParam1;
  96.  
  97.   /************************************
  98.   * Check for Illegal Flags
  99.   *************************************/
  100.  
  101.   ulCloseFlags &= ~(MCI_WAIT + MCI_NOTIFY + MCI_CLOSE_EXIT) ;
  102.  
  103.   if (ulCloseFlags > 0)
  104.       return MCIERR_INVALID_FLAG;
  105.  
  106.   /****************************************
  107.   * If There are any Pending Notifies
  108.   * Post Abort Message for Those Operations
  109.   *****************************************/
  110.  
  111.   GetNotifyAbortAccess( ulpInstance, &ulAbortNotify );
  112.  
  113.   /******************************************************
  114.   * Fix for MMPM/2 AVC--they do repeated close and after
  115.   * approximately 80 closes, due to some OS/2 scheduling
  116.   * quirk, close would free the instance before the thread
  117.   * finished processing.  Therefore, require close to
  118.   * acquire the exclusive semaphore before freeing
  119.   * instance.
  120.   ********************************************************/
  121.  
  122.  
  123.    DosRequestMutexSem( ulpInstance->hmtxCloseAccess, -1 );
  124.  
  125.    /* Release semaphore since this will be the last command for this instance */
  126.  
  127.    DosReleaseMutexSem( ulpInstance->hmtxCloseAccess );
  128.  
  129.  
  130.  
  131.   if ( ulAbortNotify == TRUE)
  132.      {
  133.  
  134.      /* Stop the command on another thread */
  135.  
  136.      GenericThreadAbort( ulpInstance, pFuncBlock, ulParam1  );
  137.  
  138.  
  139. //     if ( ulpInstance->usNotPendingMsg == MCI_SAVE )
  140. //        {
  141. //        /******************************************
  142. //        * Save is a non-interruptible operation
  143. //        * wait for completion
  144. //        ******************************************/
  145. //
  146. //        DosWaitEventSem( ulpInstance->hThreadSem, (ULONG ) -1 );
  147. //
  148. //        }
  149. //      else
  150. //        {
  151. //        /******************************************
  152. //        * If any other operation is processing, then
  153. //        * terminate them (i.e. even if we are
  154. //        * recording, the user does not want to save
  155. //        * the file so just send the aborted message
  156. //        ******************************************/
  157. //
  158. //        PostMDMMessage (MCI_NOTIFY_ABORTED,
  159. //                        ulpInstance->usNotPendingMsg,
  160. //                        pFuncBlock);
  161. //
  162. //        /***********************************************
  163. //        * Both play and record will create a thread.
  164. //        * We need to ensure that the thread will be
  165. //        * removed on a close.
  166. //        * If this is an exit list, a stop will cause a
  167. //        * hang since some necessary threads will not
  168. //        * exist anymore.
  169. //        ************************************************/
  170. //
  171. //      if (  !(ulParam1 & MCI_CLOSE_EXIT)  )
  172. //         {
  173. //         /* Stop the command on another thread */
  174. //
  175. //         ThreadedStop( ulpInstance );
  176. //         }
  177. //
  178. //        ulpInstance->usNotifyPending = FALSE;
  179. //
  180. //        }
  181.      } /* Pending Notifies */
  182.  
  183.   /***************************************
  184.   * Destroy the Stream if we have
  185.   * created one
  186.   ***************************************/
  187. // CONNECTION FEATURE
  188. #ifndef CONNECTION
  189.   if (ulpInstance->StreamInfo.hStream != (ULONG) NULL)
  190.      {
  191.      //6421
  192.      ulrc = DestroyStream ( ulpInstance);
  193.      }
  194. #endif
  195. // CONNECTION FEATURE
  196.  
  197.   /* If we installed a protocol removed it */
  198.   if ( ulpInstance->fInstalledProtocol )
  199.      {
  200.      /* Install the protocol */
  201.  
  202.      SpiInstallProtocol( hidBTarget,
  203.                          &STREAM.SpcbKey,
  204.                          &ulpInstance->StreamInfo.spcb,
  205.                          SPI_DEINSTALL_PROTOCOL );
  206.  
  207.      }
  208.   /************************************************
  209.   * If a file was previously opened then close it
  210.   * (however, if it was opened with the OPEN_MMIO
  211.   * flag, then don't close it.  That is the
  212.   * applications responsibility).
  213.   ************************************************/
  214.  
  215.   ulrc = CloseFile( ulpInstance );
  216.  
  217.   if ( ulrc )
  218.      {
  219.      return ( ulrc );
  220.      }
  221.  
  222.   /*------------------------------------------
  223.   * Free the memory of any cuepoints we have
  224.   * created.
  225.   *------------------------------------------*/
  226.  
  227.   if ( (ulpInstance->usCuePt == TRUE) ||
  228.        (ulpInstance->usCuePt == EVENT_ENABLED))
  229.      {
  230.      pCuePoint = CUEPOINT;
  231.  
  232.      while ( pCuePoint )
  233.         {
  234.         pTempCuePoint = pCuePoint;
  235.         pCuePoint = pCuePoint->pNextEVCB;
  236.         CleanUp ((PVOID) pTempCuePoint);
  237.         } /* while there are cue points to remove */
  238.  
  239.      } /* if we have cue points in use */
  240.  
  241.   /* Remove any undo nodes if they were allocated */
  242.  
  243.   RemoveUndoNodes( ulpInstance );
  244.  
  245.  
  246.   // 6421--we no longer always know if we are connected
  247.  
  248. // CONNECTION FEATURE
  249. #ifndef CONNECTION
  250. //  if ( ulpInstance->fConnected )
  251. //     {
  252.      /*******************************************
  253.      * Break The Default Amp/Mixer Connection
  254.      * The connected device will not allow a close
  255.      * before the connection is broken.
  256.      ********************************************/
  257.  
  258.      ulrc = mciConnection (ulpInstance->usWaveDeviceID,
  259.                            1,
  260.                            ulpInstance->usAmpDeviceID,
  261.                            1,
  262.                            MCI_BREAKCONNECTION);
  263.  
  264.      /****************************************
  265.      * Close The what we are connected to.
  266.      * Most often this will be the amp/mixer.
  267.      * However, if we are connected to another
  268.      * device, close it.  This call will remove
  269.      * any ability to talk to the audio device.
  270.      *****************************************/
  271.  
  272.      ulrc = mciSendCommand ((WORD)ulpInstance->usAmpDeviceID,
  273.                             MCI_CLOSE,
  274.                             MCI_WAIT,
  275.                             0,
  276.                             0);
  277. //     }
  278. #endif
  279. // CONNECTION FEATURE
  280.  
  281.   /*******************************************
  282.   * Close Internal Semaphores
  283.   *******************************************/
  284.   DosCloseEventSem (ulpInstance->hEventSem);
  285.   DosCloseEventSem (ulpInstance->hThreadSem);
  286.   DosCloseMutexSem (ulpInstance->hmtxDataAccess);
  287.   DosCloseMutexSem (ulpInstance->hmtxNotifyAccess);
  288.   DosCloseMutexSem (ulpInstance->hmtxSaveAccess);    //@12182
  289.  
  290. // avc
  291.   DosCloseMutexSem (ulpInstance->hmtxCloseAccess);
  292.  
  293.  
  294.   /*****************************************
  295.   * Post Close Complete message If needed
  296.   *****************************************/
  297.  
  298.   if (ulParam1 & MCI_NOTIFY)
  299.      {
  300.       PostMDMMessage ( MCI_NOTIFY_SUCCESSFUL, MCI_CLOSE, pFuncBlock);
  301.      }
  302.  
  303.   /*******************************************
  304.   * Free Thread Parm Block & Assoc Pointers
  305.   *******************************************/
  306.   if ( pFuncBlock->pInstance->pcodecini )
  307.      {
  308.      CleanUp( ( PVOID ) pFuncBlock->pInstance->pcodecini );
  309.      }
  310.   CleanUp ((PVOID) pFuncBlock->pInstance);
  311.  
  312.   return (MCIERR_SUCCESS);     // Return Success
  313. } /* MCIClose */
  314.  
  315.