00001 /* 00002 // $Id: //open/dev/fennel/device/DeviceAccessScheduler.cpp#15 $ 00003 // Fennel is a library of data storage and processing components. 00004 // Copyright (C) 2005-2009 The Eigenbase Project 00005 // Copyright (C) 2005-2009 SQLstream, Inc. 00006 // Copyright (C) 2005-2009 LucidEra, Inc. 00007 // Portions Copyright (C) 1999-2009 John V. Sichi 00008 // 00009 // This program is free software; you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by the Free 00011 // Software Foundation; either version 2 of the License, or (at your option) 00012 // any later version approved by The Eigenbase Project. 00013 // 00014 // This program is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with this program; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 #include "fennel/common/CommonPreamble.h" 00025 #include "fennel/device/DeviceAccessScheduler.h" 00026 #include "fennel/device/DeviceAccessSchedulerParams.h" 00027 #include "fennel/device/ThreadPoolScheduler.h" 00028 #include "fennel/device/RandomAccessDevice.h" 00029 #include "fennel/device/RandomAccessRequest.h" 00030 #include "fennel/common/FennelExcn.h" 00031 #include "fennel/common/FennelResource.h" 00032 00033 #ifdef __MSVC__ 00034 #include "fennel/device/IoCompletionPortScheduler.h" 00035 #include "fennel/common/SysCallExcn.h" 00036 #include <windows.h> 00037 #else 00038 #include <dlfcn.h> 00039 #endif 00040 00041 #ifdef USE_AIO_H 00042 #include "fennel/device/AioPollingScheduler.h" 00043 #include "fennel/device/AioSignalScheduler.h" 00044 #endif 00045 00046 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/device/DeviceAccessScheduler.cpp#15 $"); 00047 00048 #ifdef USE_LIBAIO_H 00049 static DeviceAccessScheduler *dlopenAioLinuxScheduler( 00050 DeviceAccessSchedulerParams const ¶ms) 00051 { 00052 // TODO jvs 4-Sept-2006: add corresponding dlclose if anyone cares 00053 void *hLib = dlopen("libfennel_device_aio.so", RTLD_NOW | RTLD_GLOBAL); 00054 if (!hLib) { 00055 return NULL; 00056 } 00057 void *pFactory = dlsym(hLib, "newAioLinuxScheduler"); 00058 if (!pFactory) { 00059 return NULL; 00060 } 00061 typedef DeviceAccessScheduler *(*PDeviceAccessSchedulerFactory)( 00062 DeviceAccessSchedulerParams const &); 00063 PDeviceAccessSchedulerFactory pSchedulerFactory = 00064 (PDeviceAccessSchedulerFactory) pFactory; 00065 return (*pSchedulerFactory)(params); 00066 } 00067 #endif 00068 00069 DeviceAccessScheduler * 00070 DeviceAccessScheduler::newScheduler( 00071 DeviceAccessSchedulerParams const ¶ms) 00072 { 00073 switch (params.schedulerType) { 00074 case DeviceAccessSchedulerParams::THREAD_POOL_SCHEDULER: 00075 return new ThreadPoolScheduler(params); 00076 00077 #ifdef __MSVC__ 00078 case DeviceAccessSchedulerParams::IO_COMPLETION_PORT_SCHEDULER: 00079 return new IoCompletionPortScheduler(params); 00080 #endif 00081 00082 #ifdef USE_LIBAIO_H 00083 case DeviceAccessSchedulerParams::AIO_LINUX_SCHEDULER: 00084 { 00085 DeviceAccessScheduler *pScheduler = dlopenAioLinuxScheduler(params); 00086 if (pScheduler) { 00087 return pScheduler; 00088 } else { 00089 // if the aioLinux scheduler was explicitly selected (vs simply 00090 // using the default type for the OS), then the AIO runtime 00091 // library must be installed; otherwise, fall through to use 00092 // ThreadPoolScheduler as fallback 00093 if (params.usingDefaultSchedulerType) { 00094 break; 00095 } 00096 throw FennelExcn(FennelResource::instance().libaioRequired()); 00097 } 00098 } 00099 #endif 00100 00101 #ifdef USE_AIO_H 00102 case DeviceAccessSchedulerParams::AIO_POLLING_SCHEDULER: 00103 return new AioPollingScheduler(params); 00104 case DeviceAccessSchedulerParams::AIO_SIGNAL_SCHEDULER: 00105 return new AioSignalScheduler(params); 00106 #endif 00107 00108 default: 00109 // fall through to use ThreadPoolScheduler as a fallback 00110 break; 00111 } 00112 return new ThreadPoolScheduler(params); 00113 } 00114 00115 DeviceAccessScheduler::~DeviceAccessScheduler() 00116 { 00117 } 00118 00119 RandomAccessRequestBinding::RandomAccessRequestBinding() 00120 { 00121 #ifdef __MSVC__ 00122 // TODO: only create this when ThreadPoolScheduler is being used? 00123 hEvent = CreateEvent(NULL,1,0,NULL); 00124 if (!hEvent) { 00125 throw new SysCallExcn("CreateEvent failed"); 00126 } 00127 #endif 00128 } 00129 00130 RandomAccessRequestBinding::~RandomAccessRequestBinding() 00131 { 00132 #ifdef __MSVC__ 00133 CloseHandle(hEvent); 00134 #endif 00135 } 00136 00137 void RandomAccessRequest::execute() 00138 { 00139 pDevice->transfer(*this); 00140 } 00141 00142 void DeviceAccessScheduler::registerDevice( 00143 SharedRandomAccessDevice) 00144 { 00145 } 00146 00147 void DeviceAccessScheduler::unregisterDevice( 00148 SharedRandomAccessDevice) 00149 { 00150 } 00151 00152 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/device/DeviceAccessScheduler.cpp#15 $"); 00153 00154 // End DeviceAccessScheduler.cpp