The world's most popular open source database
00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #ifndef AsyncFile_H 00018 #define AsyncFile_H 00019 00020 //=========================================================================== 00021 // 00022 // .DESCRIPTION 00023 // Asynchronous file, All actions are executed concurrently with other 00024 // activity of the process. 00025 // Because all action are performed in a seperated thread the result of 00026 // of a action is send back tru a memory channel. 00027 // For the asyncronise notivication of a finished request all the calls 00028 // have a request as paramater, the user can use the userData pointer 00029 // to add information it needs when the request is send back. 00030 // 00031 // 00032 // .TYPICAL USE: 00033 // Writing or reading data to/from disk concurrently to other activities. 00034 // 00035 //=========================================================================== 00036 //============================================================================= 00037 // 00038 // .PUBLIC 00039 // 00040 //============================================================================= 00042 // 00043 // AsyncFile( ); 00044 // Description: 00045 // Initialisation of the class. 00046 // Parameters: 00047 // - 00049 // 00050 // ~AsyncFile( ); 00051 // Description: 00052 // Tell the thread to stop and wait for it to return 00053 // Parameters: 00054 // - 00056 // 00057 // doStart( ); 00058 // Description: 00059 // Spawns the new thread. 00060 // Parameters: 00061 // Base path of filesystem 00062 // 00064 // 00065 // void execute(Request *request); 00066 // Description: 00067 // performens the requered action. 00068 // Parameters: 00069 // request: request to be called when open is finished. 00070 // action= open|close|read|write|sync 00071 // if action is open then: 00072 // par.open.flags= UNIX open flags, see man open 00073 // par.open.name= name of the file to open 00074 // if action is read or write then: 00075 // par.readWrite.buf= user provided buffer to read/write 00076 // the data from/to 00077 // par.readWrite.size= how many bytes must be read/written 00078 // par.readWrite.offset= absolute offset in file in bytes 00079 // return: 00080 // return values are stored in the request error field: 00081 // error= return state of the action, UNIX error see man open/errno 00082 // userData= is untouched can be used be user. 00083 // 00085 // 00086 // void reportTo( MemoryChannel<Request> *reportTo ); 00087 // Description: 00088 // set the channel where the file must report the result of the 00089 // actions back to. 00090 // Parameters: 00091 // reportTo: the memory channel to use use MemoryChannelMultipleWriter 00092 // if more 00093 // than one file uses this channel to report back. 00094 // 00096 00097 #include <kernel_types.h> 00098 #include "MemoryChannel.hpp" 00099 #include "Filename.hpp" 00100 00101 const int ERR_ReadUnderflow = 1000; 00102 00103 const int WRITECHUNK = 262144; 00104 00105 class AsyncFile; 00106 00107 class Request 00108 { 00109 public: 00110 enum Action { 00111 open, 00112 close, 00113 closeRemove, 00114 read, // Allways leave readv directly after 00115 // read because SimblockAsyncFileSystem depends on it 00116 readv, 00117 write,// Allways leave writev directly after 00118 // write because SimblockAsyncFileSystem depends on it 00119 writev, 00120 writeSync,// Allways leave writevSync directly after 00121 // writeSync because SimblockAsyncFileSystem depends on it 00122 writevSync, 00123 sync, 00124 end, 00125 append, 00126 rmrf, 00127 readPartial 00128 }; 00129 Action action; 00130 union { 00131 struct { 00132 Uint32 flags; 00133 Uint32 page_size; 00134 Uint64 file_size; 00135 } open; 00136 struct { 00137 int numberOfPages; 00138 struct{ 00139 char *buf; 00140 size_t size; 00141 off_t offset; 00142 } pages[16]; 00143 } readWrite; 00144 struct { 00145 const char * buf; 00146 size_t size; 00147 } append; 00148 struct { 00149 bool directory; 00150 bool own_directory; 00151 } rmrf; 00152 } par; 00153 int error; 00154 00155 void set(BlockReference userReference, 00156 Uint32 userPointer, 00157 Uint16 filePointer); 00158 BlockReference theUserReference; 00159 Uint32 theUserPointer; 00160 Uint16 theFilePointer; 00161 // Information for open, needed if the first open action fails. 00162 AsyncFile* file; 00163 Uint32 theTrace; 00164 }; 00165 00166 NdbOut& operator <<(NdbOut&, const Request&); 00167 00168 inline 00169 void 00170 Request::set(BlockReference userReference, 00171 Uint32 userPointer, Uint16 filePointer) 00172 { 00173 theUserReference= userReference; 00174 theUserPointer= userPointer; 00175 theFilePointer= filePointer; 00176 } 00177 00178 class AsyncFile 00179 { 00180 friend class Ndbfs; 00181 public: 00182 AsyncFile(SimulatedBlock& fs); 00183 ~AsyncFile(); 00184 00185 void reportTo( MemoryChannel<Request> *reportTo ); 00186 00187 void execute( Request* request ); 00188 00189 void doStart(); 00190 // its a thread so its always running 00191 void run(); 00192 00193 bool isOpen(); 00194 00195 Filename theFileName; 00196 Request *m_current_request, *m_last_request; 00197 private: 00198 00199 void openReq(Request *request); 00200 void readReq(Request *request); 00201 void readvReq(Request *request); 00202 void writeReq(Request *request); 00203 void writevReq(Request *request); 00204 00205 void closeReq(Request *request); 00206 void syncReq(Request *request); 00207 void removeReq(Request *request); 00208 void appendReq(Request *request); 00209 void rmrfReq(Request *request, char * path, bool removePath); 00210 void endReq(); 00211 00212 int readBuffer(Request*, char * buf, size_t size, off_t offset); 00213 int writeBuffer(const char * buf, size_t size, off_t offset, 00214 size_t chunk_size = WRITECHUNK); 00215 00216 int extendfile(Request* request); 00217 void createDirectories(); 00218 00219 #ifdef NDB_WIN32 00220 HANDLE hFile; 00221 #else 00222 int theFd; 00223 #endif 00224 00225 MemoryChannel<Request> *theReportTo; 00226 MemoryChannel<Request>* theMemoryChannelPtr; 00227 00228 struct NdbThread* theThreadPtr; 00229 NdbMutex* theStartMutexPtr; 00230 NdbCondition* theStartConditionPtr; 00231 bool theStartFlag; 00232 int theWriteBufferSize; 00233 char* theWriteBuffer; 00234 00235 bool m_openedWithSync; 00236 Uint32 m_syncCount; 00237 Uint32 m_syncFrequency; 00238 public: 00239 SimulatedBlock& m_fs; 00240 Ptr<GlobalPage> m_page_ptr; 00241 }; 00242 00243 #endif
1.4.7

