/* Copyright (c) 2003-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "SHM_Transporter.hpp" #include "TransporterInternalDefinitions.hpp" #include #include #include #include void SHM_Transporter::make_error_info(char info[], int sz) { snprintf(info,sz,"Shm key=%d sz=%d", shmKey, shmSize); } bool SHM_Transporter::connectServer(Uint32 timeOutMillis){ if(!_shmSegCreated) { char szName[32]; sprintf(szName, "ndb%lu", shmKey); hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, shmSize, szName); if(!hFileMapping) { reportThreadError(remoteNodeId, TE_SHM_UNABLE_TO_CREATE_SEGMENT); NdbSleep_MilliSleep(timeOutMillis); return false; } _shmSegCreated = true; } if(!_attached){ shmBuf = (char*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if(shmBuf == 0){ reportThreadError(remoteNodeId, TE_SHM_UNABLE_TO_ATTACH_SEGMENT); NdbSleep_MilliSleep(timeOutMillis); return false; } volatile Uint32 * sharedCountAttached = (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*)); ++*sharedCountAttached; _attached = true; } volatile Uint32 * sharedCountAttached = (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*)); if(*sharedCountAttached == 2 && !setupBuffersDone) { setupBuffers(); setupBuffersDone=true; } if(*sharedCountAttached > 2) { reportThreadError(remoteNodeId, TE_SHM_DISCONNECT); return false; } if(setupBuffersDone) { NdbSleep_MilliSleep(timeOutMillis); if(*serverStatusFlag==1 && *clientStatusFlag==1) return true; } NdbSleep_MilliSleep(timeOutMillis); return false; } bool SHM_Transporter::connectClient(Uint32 timeOutMillis){ if(!_shmSegCreated) { char szName[32]; sprintf(szName, "ndb%lu", shmKey); hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName); if(!hFileMapping) { NdbSleep_MilliSleep(timeOutMillis); return false; } _shmSegCreated = true; } if(!_attached){ shmBuf = (char*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if(shmBuf == 0){ reportThreadError(remoteNodeId, TE_SHM_UNABLE_TO_ATTACH_SEGMENT); NdbSleep_MilliSleep(timeOutMillis); return false; } volatile Uint32 * sharedCountAttached = (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*)); ++*sharedCountAttached; _attached = true; } volatile Uint32 * sharedCountAttached = (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*)); if(*sharedCountAttached == 2 && !setupBuffersDone) { setupBuffers(); setupBuffersDone=true; } if(setupBuffersDone) { if(*serverStatusFlag==1 && *clientStatusFlag==1) return true; } NdbSleep_MilliSleep(timeOutMillis); return false; } bool SHM_Transporter::checkConnected(){ volatile Uint32 * sharedCountAttached = (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*)); if(*sharedCountAttached != 2) { reportError(callbackObj, remoteNodeId, TE_SHM_DISCONNECT); return false; } return true; } void SHM_Transporter::disconnectImpl(){ if(_attached) { volatile Uint32 * sharedCountAttached = (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*)); --*sharedCountAttached; if(!UnmapViewOfFile(shmBuf)) { reportError(callbackObj, remoteNodeId, TE_SHM_UNABLE_TO_REMOVE_SEGMENT); return; } _attached = false; if(!isServer && _shmSegCreated) _shmSegCreated = false; } if(_shmSegCreated){ if(!CloseHandle(hFileMapping)) { reportError(callbackObj, remoteNodeId, TE_SHM_UNABLE_TO_REMOVE_SEGMENT); return; } _shmSegCreated = false; } setupBuffersDone=false; }