home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* Copyright (c) IBM Corporation 1992 */
- /* All Rights Reserved */
- /* */
- /* SOURCE FILE NAME: FSSHWRIT.C */
- /* */
- /* DESCRIPTIVE NAME: File System Stream Handler Write routine */
- /* */
- /* FUNCTION: This function is the routine that writes an object to the */
- /* file system. */
- /* */
- /* ENTRY POINTS: FsshWrite */
- /* */
- /*************************** END OF SPECIFICATIONS **************************/
- #define INCL_NOPMAPI /* no PM include files required */
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSPROCESS
- #define INCL_DOSERRORS
- #define INCL_MMIO
- #include <os2.h>
- #include <os2me.h>
- #include <hhpheap.h>
- #include <shi.h>
-
- /************************** START OF SPECIFICATIONS *************************/
- /* */
- /* SUBROUTINE NAME: FsshWrite */
- /* */
- /* DESCRIPTIVE NAME: File System Stream Handler Write routine */
- /* */
- /* FUNCTION: Gets data from source stream handler (actually SSM) and writes */
- /* it to the file system. */
- /* NOTES: */
- /* */
- /* ENTRY POINT: FsshWrite */
- /* LINKAGE: CALL NEAR (0:32) */
- /* */
- /* INPUT: */
- /* */
- /* EXIT-NORMAL: */
- /* */
- /* EXIT-ERROR: */
- /* */
- /* SIDE EFFECTS: */
- /* */
- /* INTERNAL REFERENCES: */
- /* ROUTINES: */
- /* */
- /* EXTERNAL REFERENCES: */
- /* ROUTINES: */
- /* DATA STRUCTURES: */
- /* */
- /*************************** END OF SPECIFICATIONS **************************/
-
- RC FsshWrite(psib)
- PSIB psib; // Stream Instance Block
-
- { /* Start of FsshWrite */
-
- RC rc = NO_ERROR; // local return code
- char NeedBuf; // local loop boolean
- LONG NumBytesIO; // Number of bytes from mmio
- PARM_NOTIFY npget, npret; // parms for SMH_NOTIFY calls
- TGTBUFTAB TgtBufTab = {0}; // Target buffer table
- ULONG ulStopped = DONT_SLEEP_FLUSH; // did we get stop discard or flush
- BOOL bAtEOS = FALSE; // End of Stream indicator
- ULONG ulPostCount; // Temp to hold count
-
- //
- // Before we start lets do some init stuff:
- //
- npget.ulFunction = SMH_NOTIFY;
- npget.hid = psib->HandlerID;
- npget.hstream = psib->hStream;
- npget.ulFlags = BUF_GETFULL;
- npget.ulGetNumEntries = 1L;
- npget.ulRetNumEntries = 0L;
- npget.pGetBufTab = &TgtBufTab;
- npget.pRetBufTab = NULL;
-
- npret.ulFunction = SMH_NOTIFY;
- npret.hid = psib->HandlerID;
- npret.hstream = psib->hStream;
- npret.ulFlags = BUF_RETURNEMPTY;
- npret.ulGetNumEntries = 0L;
- npret.ulRetNumEntries = 1L;
- npret.pGetBufTab = NULL;
- npret.pRetBufTab = &TgtBufTab;
-
- //
- // Wait until we get the ShcStart
- //
- DosWaitEventSem(psib->hevStop, SEM_INDEFINITE_WAIT);
-
- //
- // We will loop forever getting a full buffer, calling the file system to
- // write it out and returning the empty buffer to the stream manager.
- // During each iteration of the loop we will check the action flags for
- // asynchronous requests to do things.
- //
-
- if (psib->ulActionFlags & SIBACTFLG_KILL)
- { /* Must have been a create error */
- rc = 1L;
- } /* Must have been a create error */
-
- //
- // Start the main loop
- //
-
- while (!rc)
- { /* while no severe error */
-
- if (psib->ulActionFlags)
- rc = CheckNSleep(psib);
-
- /*
- * Get a buffer
- */
- NeedBuf = TRUE;
- while ((NeedBuf) && (!rc))
- { /* while we don't have a buffer */
-
- //
- // Clear the stop sem, so if after we call ssm to get a buffer if
- // it returns none avail then we won't miss a SSMBuffer Start before
- // we go to sleep.
- //
- DosResetEventSem(psib->hevStop, &ulPostCount);
-
- //
- // Make sure only GetFull flag is on and call ssm to get a buffer
- //
- npget.ulFlags = BUF_GETFULL;
- rc = SMHEntryPoint(&npget); /* get a buffer */
- if (!rc)
- {
- NeedBuf = FALSE;
- /* set return buffer EOS flag if get EOS is on */
- npret.ulFlags |= npget.ulFlags & BUF_EOS;
- }
- else
- { /* return code from smhnotify */
- if (rc == ERROR_BUFFER_NOT_AVAILABLE)
- { /* buffer not available */
-
- /* the smhnotify resets the num entries when none avail */
- npget.ulGetNumEntries = 1L;
- ulStopped = DONT_SLEEP_FLUSH;
- rc = SleepNCheck(psib, &ulStopped);
-
- } /* buffer not available */
- } /* return code from smhnotify */
- } /* while we don't have a buffer */
-
- //
- // We have a buffer or an error
- //
-
- if (!rc)
- { /* have a buffer */
- //
- // Check to see if we got a cuepoint in the buf attribute field.
- // If so, we need to report this event.
- //
- if (TgtBufTab.ulMessageParm)
- {
- rc = ReportEvent(psib,
- 0L, // no return code
- EVENT_PLAYLISTCUEPOINT, // event type
- TgtBufTab.ulMessageParm, // user supplied value
- 0L);
-
- }
- //
- // Make sure attribute is clear in all cases so it won't be passed
- // around the system inadvertently
- //
- TgtBufTab.ulMessageParm = 0L;
-
- //
- // If there is data in the buffer we received then write it out.
- //
- NumBytesIO = 0L;
- if (TgtBufTab.ulLength)
- {
- NumBytesIO = mmioWrite((HMMIO)psib->ulAssocP1,
- (PCHAR)TgtBufTab.pBuffer,
- (LONG)TgtBufTab.ulLength);
- }
- if ((NumBytesIO == -1L) ||
- (NumBytesIO != (LONG)TgtBufTab.ulLength))
-
- { /* an error */
-
- /* get the real error code */
- rc = mmioGetLastError((HMMIO)psib->ulAssocP1);
-
- rc = ShIOError(psib, npret, rc);
-
- } /* an error */
- else
- { /* We wrote ok */
-
- // Set up to return buffer to stream manager
-
- if (npret.ulFlags & BUF_EOS)
- { /* End of stream */
- bAtEOS = TRUE;
- DosResetEventSem(psib->hevStop, &ulPostCount);
- } /* End of stream */
-
- // Return the empty buffer to the stream manager
-
- if (!(rc = SMHEntryPoint(&npret)))
- { /* buffer returned */
- if (bAtEOS)
- {
- bAtEOS = FALSE;
- ulStopped = DONT_SLEEP_FLUSH;
- rc = SleepNCheck(psib, &ulStopped);
- }
- } /* buffer returned */
- } /* We wrote ok */
- //
- // Make sure EOS is turned off, so things will work if the
- // stream is restarted.
- //
- npret.ulFlags = BUF_RETURNEMPTY;
-
- } /* have a buffer */
-
- } /* while no severe error */
-
- //
- // We get here if an error has occurred or a kill has
- // been sent. In the case of the kill, reset the
- // return code to 0 (no error) and exit the thread.
- // Otherwise, report the error event and exit the
- // thread.
- //
-
- if (psib->ulActionFlags & SIBACTFLG_KILL)
- {
- rc = 0L;
- }
- else
- {
- ReportEvent(psib,
- rc, // Return code
- EVENT_ERROR, // event type
- 0L, // user info
- NONRECOVERABLE_ERROR); // Severe Error
- }
-
- //
- // Only set this flag when we no longer need access to the sib since
- // Destroy may get control and Free the sib.
- //
- psib->ulActionFlags |= SIBACTFLG_THREAD_DEAD;
- return(rc);
-
- } /* End of FsshWrite */
-