///////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2005-2017 Dawson Dean // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ///////////////////////////////////////////////////////////////////////////// // // BuildingBlocks // // The buildingBlocks initializes a hierarchy of modules. Really, this hierarchy // is only significant when you have to port the buildingBlocks to another // platform. All software aboive the buildingBlocks treats it as a single // large statically linked library, like the C runtime. // // // buildingBlocksManager.cpp // //------------------------------------------------------------ // Above this level, all modules can use serialized objects //------------------------------------------------------------ // // serializedObject.cpp // //------------------------------------------------------------ // Above this level, all modules can use HTTP and XML //------------------------------------------------------------ // // polyXMLDocText.cpp // polyXMLDoc.cpp // // polyHTTPStreamBasic.cpp // polyHTTPStream.cpp // // *** LOGGING IS USED BELOW HERE // //------------------------------------------------------------ // Above this level, all modules can use stream IO //------------------------------------------------------------ // // asyncIOStream.cpp // // netBlockIO.cpp // fileBlockIO.cpp // memoryBlockIO.cpp // blockIO.cpp // //------------------------------------------------------------ // Above this level, all modules can use URLs //------------------------------------------------------------ // // url.cpp // // nameTable.cpp // rbTree.cpp // // stringParse.cpp // // jobQueue.cpp // // queue.cpp // // fileUtils.cpp // //------------------------------------------------------------ // Above this level, all modules are thread safe. //------------------------------------------------------------ // // threads.cpp // //------------------------------------------------------------ // Above this level, all modules can use refcounted objects. //------------------------------------------------------------ // // refCount.cpp // //------------------------------------------------------------ // Above this level, all modules can use the debug memory heap //------------------------------------------------------------ // // memAlloc.cpp // //------------------------------------------------------------ // Above this level, all modules can use debugging utilities. //------------------------------------------------------------ // // debugging.cpp // // log.cpp // // config.cpp // // stringLib.cpp // // OSIndependantLayer.cpp // ///////////////////////////////////////////////////////////////////////////// #include "buildNumber.h" #include "buildingBlocks.h" FILE_DEBUGGING_GLOBALS(LOG_LEVEL_DEFAULT, 0); extern bool g_ShutdownBuildingBlocks; extern CDebugManager g_DebugManager; CConfigSection *g_pBuildingBlocksConfig = NULL; static char BuildingBlocksConfigKeyName[] = "BuildingBlocks"; static int32 g_FeatureLevel = 0; ///////////////////////////////////////////////////////////////////////////// // // [Initialize] // ///////////////////////////////////////////////////////////////////////////// ErrVal CBuildingBlocks::Initialize(int32 featureLevel, CProductInfo *pProductInfo) { ErrVal err = ENoErr; g_FeatureLevel = featureLevel; // If some product does not provide a valid version, then // make a generic description. if (NULL == pProductInfo) { static CProductInfo g_DefaultProductInfo; pProductInfo = &g_DefaultProductInfo; pProductInfo->m_CompanyName = "DawsonDean"; pProductInfo->m_ProductName = "TestProduct"; pProductInfo->m_MajorVersion = 1; pProductInfo->m_MinorVersion = 0; pProductInfo->m_MinorMinorVersion = 0; pProductInfo->m_Milestone = 0; pProductInfo->m_ReleaseType = CProductInfo::Release; pProductInfo->m_ReleaseNumber = 1; } // Fill in the standard part of the product version. These are // not specific to one particular product type. They instead // programmatically generated in the generic buildVersion header file. pProductInfo->m_BuildNumber = BUILD_NUMBER; pProductInfo->m_pBuildDate = BUILD_DATE; // This may be dynamically changes by a command line or // from an environment variable. if (pProductInfo->m_pHomeDirectory) { snprintf(g_SoftwareDirectoryRoot, sizeof(g_SoftwareDirectoryRoot), pProductInfo->m_pHomeDirectory); } err = OSIndependantLayer::InitializeOSIndependantLayer(); if (err) { gotoErr(err); } // Initialize this before we turn on logging. This tells // us where to put the log file. g_Config = new CConfigFile; if (NULL == g_Config) { gotoErr(EFail); } g_Config->ReadProductConfig(pProductInfo); g_pBuildingBlocksConfig = g_Config->FindOrCreateSection(BuildingBlocksConfigKeyName); if (NULL == g_pBuildingBlocksConfig) { gotoErr(EFail); } err = CDebugManager::InitializeDebugging( pProductInfo, CDebugManager::ADD_TIMESTAMP_TO_EACH_LINE | CDebugManager::ADD_FILENAME_TO_EACH_LINE // | CDebugManager::ADD_THREADID_TO_EACH_LINE | CDebugManager::ADD_FUNCTION_TO_EACH_LINE); if (err) { gotoErr(err); } err = g_MainMem.Initialize(0); if (err) { gotoErr(err); } err = CRefCountImpl::InitializeGlobalState(); if (err) { gotoErr(err); } err = CSimpleThread::InitializeModule(); if (err) { gotoErr(err); } err = CJobQueue::InitializeGlobalJobQueues(); if (err) { gotoErr(err); } err = InitializeMemoryBlockIO(); if (err) { gotoErr(err); } err = InitializeFileBlockIO(); if (err) { gotoErr(err); } if (FULL_FUNCTIONALITY == g_FeatureLevel) { err = InitializeNetBlockIO(); if (err) { gotoErr(err); } err = InitializeBasicHTTPStreamGlobalState(pProductInfo); if (err) { gotoErr(err); } } // if (xxxx == g_FeatureLevel) abort: returnErr(err); } // Initialize. ///////////////////////////////////////////////////////////////////////////// // // [Shutdown] // ///////////////////////////////////////////////////////////////////////////// void CBuildingBlocks::Shutdown() { if (FULL_FUNCTIONALITY == g_FeatureLevel) { if (g_pNetIOSystem) { (void) g_pMemoryIOSystem->Shutdown(); } } if (g_pMemoryIOSystem) { (void) g_pMemoryIOSystem->Shutdown(); } if (g_pFileIOSystem) { (void) g_pFileIOSystem->Shutdown(); } CJobQueue::ShutdownGlobalJobQueues(); CDebugManager::ShutdownDebugging(); OSIndependantLayer::ShutdownOSIndependantLayer(); // All future deallocators will not work, since we are about to // shut down the memory system. g_ShutdownBuildingBlocks = true; } // Shutdown ///////////////////////////////////////////////////////////////////////////// // // [PrepareEngineToRecordAllocations] // ///////////////////////////////////////////////////////////////////////////// void PrepareEngineToRecordAllocations(bool fInIOCallback) { UNUSED_PARAM(fInIOCallback); /////////////////////// #if 0 int32 numAllowedActiveCallbacks = 0; if (fInIOCallback) { numAllowedActiveCallbacks = 1; } // Do this first, because some buffers (IOEvents) will // be released as idle buffers. while (CIOSystem::GetTotalActiveIOJobs() > numAllowedActiveCallbacks) { Sleep(10); } g_NetIOSystem.WaitForAllBlockIOsToClose(); #endif CRefCountImpl::EmptyPendingDeleteList(); } // PrepareEngineToRecordAllocations ///////////////////////////////////////////////////////////////////////////// // // [TestBuildingBlocks] // ///////////////////////////////////////////////////////////////////////////// void CBuildingBlocks::TestBuildingBlocks() { #if INCLUDE_REGRESSION_TESTS // Initialize the world for a testing client. CBuildingBlocks::Initialize(CBuildingBlocks::FULL_FUNCTIONALITY, NULL); g_DebugManager.StartAllTests(); //OSIndependantLayer::TestOSIndependantLayer(); //CStringLib::TestStringLib(); //CConfigFile::TestConfig(); //CEventLog::TestLog(); //CMemAlloc::TestAlloc(); //CRefCountImpl::TestRefCounting(); //CSimpleThread::TestThreads(); //TestQueue(); //CJobQueue::TestJobQueue(); //CRBTree::TestTree(); //CNameTable::TestNameTable(); //CParsedUrl::TestURL(); //CIOSystem::TestBlockIO(); //CAsyncIOStream::TestAsyncIOStream(); //CPolyHttpStream::TestHTTPStream(); CPolyXMLDoc::TestXMLModule(); g_DebugManager.EndAllTests(); CBuildingBlocks::Shutdown(); //OSIndependantLayer::PrintToConsole("\nDone\n"); #endif // INCLUDE_REGRESSION_TESTS } // TestBuildingBlocks ///////////////////////////////////////////////////////////////////////////// // // [TestBuildingBlocks] // ///////////////////////////////////////////////////////////////////////////// void TestBuildingBlocks() { CBuildingBlocks::TestBuildingBlocks(); } // TestBuildingBlocks