void Context::shutdown() { --m_initializationCounter; if (m_initializationCounter > 0) { xnLogInfo(XN_LOG_MASK_ALL, "Shutdown: still need %d more shutdown calls (to match initializations)", m_initializationCounter); return; } if (!s_valid) { return; } s_valid = FALSE; m_cs.Lock(); // Close all recorders. while (m_recorders.Begin() != m_recorders.End()) { Recorder* pRecorder = *m_recorders.Begin(); recorderClose(pRecorder); } // Destroy all streams while (m_streams.Begin() != m_streams.End()) { VideoStream* pStream = *m_streams.Begin(); streamDestroy(pStream); } // Close all devices while (m_devices.Begin() != m_devices.End()) { Device* pDevice = *m_devices.Begin(); m_devices.Remove(pDevice); pDevice->close(); XN_DELETE(pDevice); } for (xnl::List<DeviceDriver*>::Iterator iter = m_deviceDrivers.Begin(); iter != m_deviceDrivers.End(); ++iter) { DeviceDriver* pDriver = *iter; XN_DELETE(pDriver); } m_deviceDrivers.Clear(); m_newFrameAvailableEvent.Close(); m_cs.Unlock(); xnLogClose(); }
OniStatus Context::recorderClose(OniRecorderHandle* pRecorder) { // Validate parameters. if (NULL == pRecorder) { return ONI_STATUS_BAD_PARAMETER; } // NOTE: // The way handles are related to Recorder instance can be depicted by such // a diagram: // // +----------------------------+ points to // | OniRecorderHandle handle_1 |-----------------+ // +----------------------------+ | // +----------------------------+ points to +-----v------------------+ // | OniRecorderHandle handle_2 |---------->| _OniRecorder instance | // +----------------------------+ |------------------------| // | Recorder* pRecorder | // +-------------------+ points to +-----|------------------+ // | Recorder instance |<-------------------------+ // +-------------------+ // // As you see, there might be two instances of OniRecorderHandle, which point // to the same Recorder instance. // // Handles do not support any reference-counting, and thus whenever somebody // destroys a Recorder instance, the instance becomes nonexistent for every // handle out there in your program. // // Moreover, a Recorder instance might own a handle to itself, and whenever // the Recorder instance is being destroyed, it NULL-fies the pRecorder // field in _OniRecorder structure. if (NULL != *pRecorder) { recorderClose((*pRecorder)->pRecorder); } // Delete the _OniRecorder data structure. XN_DELETE(*pRecorder); // Ensure, that the client no longer considers the handle being a valid one. *pRecorder = NULL; return ONI_STATUS_OK; }