Merge pull request #23771 from taosdata/enh/xsren/TD-27022/windows
Enh/xsren/td 27022/windows
This commit is contained in:
commit
1b6a3c2069
|
@ -97,7 +97,15 @@ ENDIF()
|
|||
SET(JEMALLOC_ENABLED OFF)
|
||||
IF (TD_WINDOWS)
|
||||
MESSAGE("${Yellow} set compiler flag for Windows! ${ColourReset}")
|
||||
IF (${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||
MESSAGE("${Green} will build Release version! ${ColourReset}")
|
||||
SET(COMMON_FLAGS "/W3 /D_WIN32 /DWIN32 /Zi- /O2 /GL /MD")
|
||||
|
||||
ELSE ()
|
||||
MESSAGE("${Green} will build Debug version! ${ColourReset}")
|
||||
SET(COMMON_FLAGS "/w /D_WIN32 /DWIN32 /Zi /MTd")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
|
||||
# IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
|
||||
# SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
|
||||
|
|
|
@ -317,7 +317,8 @@ if (${BUILD_WITH_ROCKSDB})
|
|||
SET(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
endif(${TD_LINUX})
|
||||
MESSAGE(STATUS "CXXXX STATUS CONFIG: " ${CMAKE_CXX_FLAGS})
|
||||
MESSAGE(STATUS "ROCKSDB CXXXX STATUS CONFIG: " ${CMAKE_CXX_FLAGS})
|
||||
MESSAGE(STATUS "ROCKSDB C STATUS CONFIG: " ${CMAKE_C_FLAGS})
|
||||
|
||||
if(${TD_DARWIN})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=maybe-uninitialized")
|
||||
|
@ -329,8 +330,12 @@ if (${BUILD_WITH_ROCKSDB})
|
|||
|
||||
if (${TD_WINDOWS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4819")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244 /wd4819")
|
||||
option(WITH_JNI "" OFF)
|
||||
if(CMAKE_C_FLAGS MATCHES "/MT" OR CMAKE_C_FLAGS MATCHES "/MTd")
|
||||
message("Rocksdb build runtime lib use /MT or /MTd")
|
||||
option(WITH_MD_LIBRARY "build with MD" OFF)
|
||||
endif()
|
||||
set(SYSTEM_LIBS ${SYSTEM_LIBS} shlwapi.lib rpcrt4.lib)
|
||||
endif(${TD_WINDOWS})
|
||||
|
||||
|
@ -361,9 +366,11 @@ if (${BUILD_WITH_ROCKSDB})
|
|||
)
|
||||
else()
|
||||
if (NOT ${TD_LINUX})
|
||||
MESSAGE(STATUS "CXXXX STATUS CONFIG: " ${CMAKE_CXX_FLAGS})
|
||||
MESSAGE(STATUS "ROCKSDB CXX STATUS CONFIG: " ${CMAKE_CXX_FLAGS})
|
||||
MESSAGE(STATUS "ROCKSDB C STATUS CONFIG: " ${CMAKE_C_FLAGS})
|
||||
if(${TD_DARWIN})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=maybe-uninitialized")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=maybe-uninitialized")
|
||||
endif(${TD_DARWIN})
|
||||
|
||||
if (${TD_DARWIN_ARM64})
|
||||
|
@ -372,8 +379,12 @@ if (${BUILD_WITH_ROCKSDB})
|
|||
|
||||
if (${TD_WINDOWS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4819")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244 /wd4819")
|
||||
option(WITH_JNI "" OFF)
|
||||
if(CMAKE_C_FLAGS MATCHES "/MT" OR CMAKE_C_FLAGS MATCHES "/MTd")
|
||||
message("Rocksdb build runtime lib use /MT or /MTd")
|
||||
option(WITH_MD_LIBRARY "build with MD" OFF)
|
||||
endif()
|
||||
set(SYSTEM_LIBS ${SYSTEM_LIBS} shlwapi.lib rpcrt4.lib)
|
||||
endif(${TD_WINDOWS})
|
||||
|
||||
|
@ -456,7 +467,9 @@ endif(${BUILD_WITH_NURAFT})
|
|||
|
||||
# pthread
|
||||
if(${BUILD_PTHREAD})
|
||||
set(CMAKE_BUILD_TYPE debug)
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
SET(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
add_definitions(-DPTW32_STATIC_LIB)
|
||||
add_subdirectory(pthread EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libpthreadVC3 PROPERTIES OUTPUT_NAME pthread)
|
||||
|
@ -640,13 +653,18 @@ if(${BUILD_GEOS})
|
|||
if(${TD_LINUX})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_REL}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_REL}")
|
||||
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
SET(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
endif(${TD_LINUX})
|
||||
option(BUILD_SHARED_LIBS "Build GEOS with shared libraries" OFF)
|
||||
add_subdirectory(geos EXCLUDE_FROM_ALL)
|
||||
if (${TD_WINDOWS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
else ()
|
||||
unset(CMAKE_CXX_STANDARD CACHE) # undo libgeos's setting of global CMAKE_CXX_STANDARD
|
||||
endif(${TD_WINDOWS})
|
||||
target_include_directories(
|
||||
geos_c
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/geos/include>
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct TdFile *TdFilePtr;
|
|||
#define TD_FILE_AUTO_DEL 0x0040
|
||||
#define TD_FILE_EXCL 0x0080
|
||||
#define TD_FILE_STREAM 0x0100 // Only support taosFprintfFile, taosGetLineFile, taosEOFFile
|
||||
#define TD_FILE_WRITE_THROUGH 0x0200
|
||||
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions);
|
||||
TdFilePtr taosCreateFile(const char *path, int32_t tdFileOptions);
|
||||
|
||||
|
|
|
@ -354,11 +354,16 @@ static int32_t taosLoadCfg(SConfig *pCfg, const char **envCmd, const char *input
|
|||
char cfgFile[PATH_MAX + 100] = {0};
|
||||
|
||||
taosExpandDir(inputCfgDir, cfgDir, PATH_MAX);
|
||||
char lastC = cfgDir[strlen(cfgDir) - 1];
|
||||
char *tdDirsep = TD_DIRSEP;
|
||||
if (lastC == '\\' || lastC == '/') {
|
||||
tdDirsep = "";
|
||||
}
|
||||
if (taosIsDir(cfgDir)) {
|
||||
#ifdef CUS_PROMPT
|
||||
snprintf(cfgFile, sizeof(cfgFile), "%s" TD_DIRSEP "%s.cfg", cfgDir, CUS_PROMPT);
|
||||
snprintf(cfgFile, sizeof(cfgFile), "%s" "%s" "%s.cfg", cfgDir, tdDirsep, CUS_PROMPT);
|
||||
#else
|
||||
snprintf(cfgFile, sizeof(cfgFile), "%s" TD_DIRSEP "taos.cfg", cfgDir);
|
||||
snprintf(cfgFile, sizeof(cfgFile), "%s" "%s" "taos.cfg", cfgDir, tdDirsep);
|
||||
#endif
|
||||
} else {
|
||||
tstrncpy(cfgFile, cfgDir, sizeof(cfgDir));
|
||||
|
|
|
@ -169,7 +169,7 @@ int32_t mmWriteFile(const char *path, const SMnodeOpt *pOption) {
|
|||
if (buffer == NULL) goto _OVER;
|
||||
terrno = 0;
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) goto _OVER;
|
||||
|
||||
int32_t len = strlen(buffer);
|
||||
|
|
|
@ -200,7 +200,7 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) {
|
|||
if (buffer == NULL) goto _OVER;
|
||||
terrno = 0;
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) goto _OVER;
|
||||
|
||||
int32_t len = strlen(buffer);
|
||||
|
|
|
@ -232,7 +232,7 @@ int32_t dmWriteEps(SDnodeData *pData) {
|
|||
if (buffer == NULL) goto _OVER;
|
||||
terrno = 0;
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) goto _OVER;
|
||||
|
||||
int32_t len = strlen(buffer);
|
||||
|
|
|
@ -120,7 +120,7 @@ int32_t dmWriteFile(const char *path, const char *name, bool deployed) {
|
|||
if (buffer == NULL) goto _OVER;
|
||||
terrno = 0;
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) goto _OVER;
|
||||
|
||||
int32_t len = strlen(buffer);
|
||||
|
|
|
@ -605,7 +605,7 @@ void mndDumpSdb() {
|
|||
char *pCont = tjsonToString(json);
|
||||
int32_t contLen = strlen(pCont);
|
||||
char file[] = "sdb.json";
|
||||
TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC| TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
mError("failed to write %s since %s", file, terrstr());
|
||||
|
|
|
@ -38,7 +38,7 @@ class MndTestTrans1 : public ::testing::Test {
|
|||
|
||||
test.ServerStop();
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
int32_t writeLen = taosWriteFile(pFile, buffer, readLen);
|
||||
if (writeLen < 0 || writeLen == readLen) {
|
||||
ASSERT(1);
|
||||
|
|
|
@ -104,7 +104,7 @@ static int32_t tsdbSaveFSToFile(STsdbFS *pFS, const char *fname) {
|
|||
taosCalcChecksumAppend(0, pData, size);
|
||||
|
||||
// save to file
|
||||
TdFilePtr pFD = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
|
||||
TdFilePtr pFD = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFD == NULL) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
|
@ -85,7 +85,7 @@ static int32_t save_json(const cJSON *json, const char *fname) {
|
|||
char *data = cJSON_PrintUnformatted(json);
|
||||
if (data == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
TdFilePtr fp = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
|
||||
TdFilePtr fp = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (fp == NULL) {
|
||||
code = TAOS_SYSTEM_ERROR(code);
|
||||
goto _exit;
|
||||
|
|
|
@ -177,7 +177,7 @@ int32_t tsdbDFileRollback(STsdb *pTsdb, SDFileSet *pSet, EDataFileT ftype) {
|
|||
taosCalcChecksumAppend(0, hdr, TSDB_FHDR_SIZE);
|
||||
|
||||
// open
|
||||
pFD = taosOpenFile(fname, TD_FILE_WRITE);
|
||||
pFD = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_WRITE_THROUGH);
|
||||
if (pFD == NULL) {
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto _err;
|
||||
|
|
|
@ -177,7 +177,7 @@ int vnodeSaveInfo(const char *dir, const SVnodeInfo *pInfo) {
|
|||
}
|
||||
|
||||
// save info to a vnode_tmp.json
|
||||
pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) {
|
||||
vError("failed to open info file:%s for write:%s", fname, terrstr());
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
|
|
|
@ -103,7 +103,7 @@ int32_t syncWriteCfgFile(SSyncNode *pNode) {
|
|||
if (buffer == NULL) goto _OVER;
|
||||
terrno = 0;
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) goto _OVER;
|
||||
|
||||
int32_t len = strlen(buffer);
|
||||
|
|
|
@ -128,7 +128,7 @@ int32_t raftStoreWriteFile(SSyncNode *pNode) {
|
|||
if (buffer == NULL) goto _OVER;
|
||||
terrno = 0;
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) goto _OVER;
|
||||
|
||||
int32_t len = strlen(buffer);
|
||||
|
|
|
@ -873,7 +873,7 @@ int walSaveMeta(SWal* pWal) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
TdFilePtr pMetaFile = taosOpenFile(tmpFnameStr, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
TdFilePtr pMetaFile = taosOpenFile(tmpFnameStr, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pMetaFile == NULL) {
|
||||
wError("vgId:%d, failed to open file due to %s. file:%s", pWal->cfg.vgId, strerror(errno), tmpFnameStr);
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
|
|
|
@ -133,6 +133,7 @@ int32_t walRollback(SWal *pWal, int64_t ver) {
|
|||
}
|
||||
|
||||
walBuildIdxName(pWal, walGetCurFileFirstVer(pWal), fnameStr);
|
||||
taosCloseFile(&pWal->pIdxFile);
|
||||
TdFilePtr pIdxFile = taosOpenFile(fnameStr, TD_FILE_WRITE | TD_FILE_READ | TD_FILE_APPEND);
|
||||
|
||||
if (pIdxFile == NULL) {
|
||||
|
@ -153,6 +154,7 @@ int32_t walRollback(SWal *pWal, int64_t ver) {
|
|||
}
|
||||
|
||||
walBuildLogName(pWal, walGetCurFileFirstVer(pWal), fnameStr);
|
||||
taosCloseFile(&pWal->pLogFile);
|
||||
TdFilePtr pLogFile = taosOpenFile(fnameStr, TD_FILE_WRITE | TD_FILE_READ | TD_FILE_APPEND);
|
||||
wDebug("vgId:%d, wal truncate file %s", pWal->cfg.vgId, fnameStr);
|
||||
if (pLogFile == NULL) {
|
||||
|
@ -204,6 +206,7 @@ int32_t walRollback(SWal *pWal, int64_t ver) {
|
|||
pWal->vers.lastVer = ver - 1;
|
||||
((SWalFileInfo *)taosArrayGetLast(pWal->fileInfoSet))->lastVer = ver - 1;
|
||||
((SWalFileInfo *)taosArrayGetLast(pWal->fileInfoSet))->fileSize = entry.offset;
|
||||
|
||||
taosCloseFile(&pIdxFile);
|
||||
taosCloseFile(&pLogFile);
|
||||
|
||||
|
@ -605,7 +608,7 @@ int32_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SWalSync
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pWal->pIdxFile == NULL || pWal->pIdxFile == NULL || pWal->writeCur < 0) {
|
||||
if (pWal->pIdxFile == NULL || pWal->pLogFile == NULL || pWal->writeCur < 0) {
|
||||
if (walInitWriteFile(pWal) < 0) {
|
||||
taosThreadMutexUnlock(&pWal->mutex);
|
||||
return -1;
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
#include <io.h>
|
||||
#include <WinBase.h>
|
||||
#include <ktmw32.h>
|
||||
#include <windows.h>
|
||||
#define F_OK 0
|
||||
#define W_OK 2
|
||||
#define R_OK 4
|
||||
|
||||
#define _SEND_FILE_STEP_ 1000
|
||||
#define _SEND_FILE_STEP_ 1024
|
||||
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
|
@ -44,12 +45,22 @@
|
|||
|
||||
typedef int32_t FileFd;
|
||||
|
||||
#ifdef WINDOWS
|
||||
typedef struct TdFile {
|
||||
TdThreadRwlock rwlock;
|
||||
int refId;
|
||||
HANDLE hFile;
|
||||
FILE* fp;
|
||||
int32_t tdFileOptions;
|
||||
} TdFile;
|
||||
#else
|
||||
typedef struct TdFile {
|
||||
TdThreadRwlock rwlock;
|
||||
int refId;
|
||||
FileFd fd;
|
||||
FILE *fp;
|
||||
} TdFile;
|
||||
#endif // WINDOWS
|
||||
|
||||
#define FILE_WITH_LOCK 1
|
||||
|
||||
|
@ -240,15 +251,12 @@ int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime, int32_t *a
|
|||
return 0;
|
||||
}
|
||||
int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) {
|
||||
if (pFile == NULL || pFile->fd < 0) {
|
||||
#ifdef WINDOWS
|
||||
if (pFile == NULL || pFile->hFile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
||||
BY_HANDLE_FILE_INFORMATION bhfi;
|
||||
HANDLE handle = (HANDLE)_get_osfhandle(pFile->fd);
|
||||
if (GetFileInformationByHandle(handle, &bhfi) == FALSE) {
|
||||
if (GetFileInformationByHandle(pFile->hFile, &bhfi) == FALSE) {
|
||||
printf("taosFStatFile get file info fail.");
|
||||
return -1;
|
||||
}
|
||||
|
@ -262,7 +270,9 @@ int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) {
|
|||
}
|
||||
|
||||
#else
|
||||
|
||||
if (pFile == NULL || pFile->fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
struct stat fileStat;
|
||||
int32_t code = fstat(pFile->fd, &fileStat);
|
||||
if (code < 0) {
|
||||
|
@ -282,10 +292,7 @@ int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
||||
int fd = -1;
|
||||
FILE *fp = NULL;
|
||||
if (tdFileOptions & TD_FILE_STREAM) {
|
||||
FILE *taosOpenFileForStream(const char *path, int32_t tdFileOptions) {
|
||||
char *mode = NULL;
|
||||
if (tdFileOptions & TD_FILE_APPEND) {
|
||||
mode = (tdFileOptions & TD_FILE_TEXT) ? "at+" : "ab+";
|
||||
|
@ -300,11 +307,333 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
|||
if (tdFileOptions & TD_FILE_EXCL) {
|
||||
return NULL;
|
||||
}
|
||||
fp = fopen(path, mode);
|
||||
if (fp == NULL) {
|
||||
return NULL;
|
||||
return fopen(path, mode);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
HANDLE taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
|
||||
DWORD openMode = 0;
|
||||
DWORD access = 0;
|
||||
DWORD fileFlag = FILE_ATTRIBUTE_NORMAL;
|
||||
DWORD shareMode = FILE_SHARE_READ;
|
||||
|
||||
openMode = OPEN_EXISTING;
|
||||
if (tdFileOptions & TD_FILE_CREATE) {
|
||||
openMode = OPEN_ALWAYS;
|
||||
} else if (tdFileOptions & TD_FILE_EXCL) {
|
||||
openMode = CREATE_NEW;
|
||||
} else if ((tdFileOptions & TD_FILE_TRUNC)) {
|
||||
openMode = TRUNCATE_EXISTING;
|
||||
access |= GENERIC_WRITE;
|
||||
}
|
||||
if (tdFileOptions & TD_FILE_APPEND) {
|
||||
access |= FILE_APPEND_DATA;
|
||||
}
|
||||
if (tdFileOptions & TD_FILE_WRITE) {
|
||||
access |= GENERIC_WRITE;
|
||||
}
|
||||
|
||||
shareMode |= FILE_SHARE_WRITE;
|
||||
|
||||
access |= GENERIC_READ;
|
||||
|
||||
if (tdFileOptions & TD_FILE_AUTO_DEL) {
|
||||
fileFlag |= FILE_ATTRIBUTE_TEMPORARY;
|
||||
}
|
||||
if (tdFileOptions & TD_FILE_WRITE_THROUGH) {
|
||||
fileFlag |= FILE_FLAG_WRITE_THROUGH;
|
||||
}
|
||||
|
||||
HANDLE h = CreateFile(path, access, shareMode, NULL, openMode, fileFlag, NULL);
|
||||
if (h != INVALID_HANDLE_VALUE && (tdFileOptions & TD_FILE_APPEND) && (tdFileOptions & TD_FILE_WRITE)) {
|
||||
SetFilePointer(h, 0, NULL, FILE_END);
|
||||
}
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
DWORD dwError = GetLastError();
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
|
||||
0,
|
||||
(LPTSTR)&lpMsgBuf, 0, NULL);
|
||||
printf("CreateFile failed with error %d: %s", dwError, (char*)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockRdlock(&(pFile->rwlock));
|
||||
#endif
|
||||
if (pFile->hFile == NULL) {
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
DWORD bytesRead;
|
||||
if (!ReadFile(pFile->hFile, buf, count, &bytesRead, NULL)) {
|
||||
bytesRead = -1;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
|
||||
if (pFile == NULL || pFile->hFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockWrlock(&(pFile->rwlock));
|
||||
#endif
|
||||
|
||||
DWORD bytesWritten;
|
||||
if (!WriteFile(pFile->hFile, buf, count, &bytesWritten, NULL)) {
|
||||
bytesWritten = -1;
|
||||
}
|
||||
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
int64_t taosPWriteFile(TdFilePtr pFile, const void *buf, int64_t count, int64_t offset) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockWrlock(&(pFile->rwlock));
|
||||
#endif
|
||||
ASSERT(pFile->hFile != NULL); // Please check if you have closed the file.
|
||||
if (pFile->hFile == NULL) {
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD ret = 0;
|
||||
OVERLAPPED ol = {0};
|
||||
ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
|
||||
ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
|
||||
|
||||
SetLastError(0);
|
||||
BOOL result = WriteFile(pFile->hFile, buf, count, &ret, &ol);
|
||||
if (!result) {
|
||||
errno = GetLastError();
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence) {
|
||||
if (pFile == NULL || pFile->hFile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockRdlock(&(pFile->rwlock));
|
||||
#endif
|
||||
|
||||
LARGE_INTEGER liOffset;
|
||||
liOffset.QuadPart = offset;
|
||||
if (!SetFilePointerEx(pFile->hFile, liOffset, NULL, whence)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
liOffset.QuadPart = 0;
|
||||
if (!SetFilePointerEx(pFile->hFile, liOffset, &liOffset, FILE_CURRENT)) {
|
||||
return -1;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return liOffset.QuadPart;
|
||||
}
|
||||
|
||||
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime) {
|
||||
if (pFile == NULL || pFile->hFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size != NULL) {
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx(pFile->hFile, &fileSize)) {
|
||||
return -1; // Error getting file size
|
||||
}
|
||||
*size = fileSize.QuadPart;
|
||||
}
|
||||
|
||||
if (mtime != NULL) {
|
||||
FILETIME creationTime, lastAccessTime, lastWriteTime;
|
||||
if (!GetFileTime(pFile->hFile, &creationTime, &lastAccessTime, &lastWriteTime)) {
|
||||
return -1; // Error getting file time
|
||||
}
|
||||
// Convert the FILETIME structure to a time_t value
|
||||
ULARGE_INTEGER ull;
|
||||
ull.LowPart = lastWriteTime.dwLowDateTime;
|
||||
ull.HighPart = lastWriteTime.dwHighDateTime;
|
||||
*mtime = (int32_t)((ull.QuadPart - 116444736000000000ULL) / 10000000ULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t taosLockFile(TdFilePtr pFile) {
|
||||
if (pFile == NULL || pFile->hFile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL fSuccess = FALSE;
|
||||
LARGE_INTEGER fileSize;
|
||||
OVERLAPPED overlapped = {0};
|
||||
|
||||
fSuccess = LockFileEx(pFile->hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
|
||||
0, // reserved
|
||||
~0, // number of bytes to lock low
|
||||
~0, // number of bytes to lock high
|
||||
&overlapped // overlapped structure
|
||||
);
|
||||
if (!fSuccess) {
|
||||
return GetLastError();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t taosUnLockFile(TdFilePtr pFile) {
|
||||
if (pFile == NULL || pFile->hFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
BOOL fSuccess = FALSE;
|
||||
OVERLAPPED overlapped = {0};
|
||||
|
||||
fSuccess = UnlockFileEx(pFile->hFile, 0, ~0, ~0, &overlapped);
|
||||
if (!fSuccess) {
|
||||
return GetLastError();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (pFile->hFile == NULL) {
|
||||
printf("Ftruncate file error, hFile was null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LARGE_INTEGER li_0;
|
||||
li_0.QuadPart = (int64_t)0;
|
||||
BOOL cur = SetFilePointerEx(pFile->hFile, li_0, NULL, FILE_CURRENT);
|
||||
if (!cur) {
|
||||
printf("SetFilePointerEx Error getting current position in file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LARGE_INTEGER li_size;
|
||||
li_size.QuadPart = l_size;
|
||||
BOOL cur2 = SetFilePointerEx(pFile->hFile, li_size, NULL, FILE_BEGIN);
|
||||
if (cur2 == 0) {
|
||||
int error = GetLastError();
|
||||
printf("SetFilePointerEx GetLastError is: %d\n", error);
|
||||
switch (error) {
|
||||
case ERROR_INVALID_HANDLE:
|
||||
errno = EBADF;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SetEndOfFile(pFile->hFile)) {
|
||||
int error = GetLastError();
|
||||
printf("SetEndOfFile GetLastError is:%d", error);
|
||||
switch (error) {
|
||||
case ERROR_INVALID_HANDLE:
|
||||
errno = EBADF;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size) {
|
||||
if (pFileOut == NULL || pFileIn == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (pFileIn->hFile == NULL || pFileOut->hFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LARGE_INTEGER fileOffset;
|
||||
fileOffset.QuadPart = *offset;
|
||||
|
||||
if (!SetFilePointerEx(pFileIn->hFile, fileOffset, &fileOffset, FILE_BEGIN)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t writeLen = 0;
|
||||
uint8_t buffer[_SEND_FILE_STEP_] = {0};
|
||||
|
||||
DWORD bytesRead;
|
||||
DWORD bytesWritten;
|
||||
for (int64_t len = 0; len < (size - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
|
||||
if (!ReadFile(pFileIn->hFile, buffer, _SEND_FILE_STEP_, &bytesRead, NULL)) {
|
||||
return writeLen;
|
||||
}
|
||||
|
||||
if (bytesRead <= 0) {
|
||||
return writeLen;
|
||||
} else if (bytesRead < _SEND_FILE_STEP_) {
|
||||
if (!WriteFile(pFileOut->hFile, buffer, bytesRead, &bytesWritten, NULL)) {
|
||||
return -1;
|
||||
} else {
|
||||
return (int64_t)(writeLen + bytesRead);
|
||||
}
|
||||
} else {
|
||||
if (!WriteFile(pFileOut->hFile, buffer, _SEND_FILE_STEP_, &bytesWritten, NULL)) {
|
||||
return -1;
|
||||
} else {
|
||||
writeLen += _SEND_FILE_STEP_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t remain = size - writeLen;
|
||||
if (remain > 0) {
|
||||
DWORD bytesRead;
|
||||
if (!ReadFile(pFileIn->hFile, buffer, (DWORD)remain, &bytesRead, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bytesRead <= 0) {
|
||||
return writeLen;
|
||||
} else {
|
||||
DWORD bytesWritten;
|
||||
if (!WriteFile(pFileOut->hFile, buffer, bytesRead, &bytesWritten, NULL)) {
|
||||
return -1;
|
||||
} else {
|
||||
writeLen += bytesWritten;
|
||||
}
|
||||
}
|
||||
}
|
||||
return writeLen;
|
||||
}
|
||||
|
||||
#else
|
||||
int taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
|
||||
int access = O_BINARY;
|
||||
access |= (tdFileOptions & TD_FILE_CREATE) ? O_CREAT : 0;
|
||||
if ((tdFileOptions & TD_FILE_WRITE) && (tdFileOptions & TD_FILE_READ)) {
|
||||
|
@ -318,80 +647,8 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
|||
access |= (tdFileOptions & TD_FILE_APPEND) ? O_APPEND : 0;
|
||||
access |= (tdFileOptions & TD_FILE_TEXT) ? O_TEXT : 0;
|
||||
access |= (tdFileOptions & TD_FILE_EXCL) ? O_EXCL : 0;
|
||||
#ifdef WINDOWS
|
||||
int32_t pmode = _S_IREAD | _S_IWRITE;
|
||||
if (tdFileOptions & TD_FILE_AUTO_DEL) {
|
||||
pmode |= _O_TEMPORARY;
|
||||
}
|
||||
fd = _open(path, access, pmode);
|
||||
#else
|
||||
fd = open(path, access, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
#endif
|
||||
if (fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TdFilePtr pFile = (TdFilePtr)taosMemoryMalloc(sizeof(TdFile));
|
||||
if (pFile == NULL) {
|
||||
if (fd >= 0) close(fd);
|
||||
if (fp != NULL) fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockInit(&(pFile->rwlock), NULL);
|
||||
#endif
|
||||
pFile->fd = fd;
|
||||
pFile->fp = fp;
|
||||
pFile->refId = 0;
|
||||
|
||||
if (tdFileOptions & TD_FILE_AUTO_DEL) {
|
||||
#ifdef WINDOWS
|
||||
// do nothing, since the property of pmode is set with _O_TEMPORARY; the OS will recycle
|
||||
// the file handle, as well as the space on disk.
|
||||
#else
|
||||
// Remove it instantly, so when the program exits normally/abnormally, the file
|
||||
// will be automatically remove by OS.
|
||||
unlink(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
return pFile;
|
||||
}
|
||||
|
||||
int32_t taosCloseFile(TdFilePtr *ppFile) {
|
||||
int32_t code = 0;
|
||||
if (ppFile == NULL || *ppFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockWrlock(&((*ppFile)->rwlock));
|
||||
#endif
|
||||
if ((*ppFile)->fp != NULL) {
|
||||
fflush((*ppFile)->fp);
|
||||
fclose((*ppFile)->fp);
|
||||
(*ppFile)->fp = NULL;
|
||||
}
|
||||
if ((*ppFile)->fd >= 0) {
|
||||
#ifdef WINDOWS
|
||||
HANDLE h = (HANDLE)_get_osfhandle((*ppFile)->fd);
|
||||
!FlushFileBuffers(h);
|
||||
#else
|
||||
// warning: never fsync silently in base lib
|
||||
/*fsync((*ppFile)->fd);*/
|
||||
#endif
|
||||
code = close((*ppFile)->fd);
|
||||
(*ppFile)->fd = -1;
|
||||
}
|
||||
(*ppFile)->refId = 0;
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&((*ppFile)->rwlock));
|
||||
taosThreadRwlockDestroy(&((*ppFile)->rwlock));
|
||||
#endif
|
||||
taosMemoryFree(*ppFile);
|
||||
*ppFile = NULL;
|
||||
return code;
|
||||
int fd = open(path, access, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
||||
|
@ -407,7 +664,7 @@ int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
|||
}
|
||||
int64_t leftbytes = count;
|
||||
int64_t readbytes;
|
||||
char *tbuf = (char *)buf;
|
||||
char * tbuf = (char *)buf;
|
||||
|
||||
while (leftbytes > 0) {
|
||||
#ifdef WINDOWS
|
||||
|
@ -441,42 +698,6 @@ int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
|||
return count;
|
||||
}
|
||||
|
||||
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockRdlock(&(pFile->rwlock));
|
||||
#endif
|
||||
ASSERT(pFile->fd >= 0); // Please check if you have closed the file.
|
||||
if (pFile->fd < 0) {
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
DWORD ret = 0;
|
||||
OVERLAPPED ol = {0};
|
||||
ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
|
||||
ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
|
||||
|
||||
HANDLE handle = (HANDLE)_get_osfhandle(pFile->fd);
|
||||
SetLastError(0);
|
||||
BOOL result = ReadFile(handle, buf, count, &ret, &ol);
|
||||
if (!result && GetLastError() != ERROR_HANDLE_EOF) {
|
||||
errno = GetLastError();
|
||||
ret = -1;
|
||||
}
|
||||
#else
|
||||
int64_t ret = pread(pFile->fd, buf, count, offset);
|
||||
#endif
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
|
@ -493,7 +714,7 @@ int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
|
|||
|
||||
int64_t nleft = count;
|
||||
int64_t nwritten = 0;
|
||||
char *tbuf = (char *)buf;
|
||||
char * tbuf = (char *)buf;
|
||||
|
||||
while (nleft > 0) {
|
||||
nwritten = write(pFile->fd, (void *)tbuf, (uint32_t)nleft);
|
||||
|
@ -706,25 +927,6 @@ int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int32_t taosFsyncFile(TdFilePtr pFile) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this implementation is WRONG
|
||||
// fflush is not a replacement of fsync
|
||||
if (pFile->fp != NULL) return fflush(pFile->fp);
|
||||
if (pFile->fd >= 0) {
|
||||
#ifdef WINDOWS
|
||||
HANDLE h = (HANDLE)_get_osfhandle(pFile->fd);
|
||||
return !FlushFileBuffers(h);
|
||||
#else
|
||||
return fsync(pFile->fd);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size) {
|
||||
if (pFileOut == NULL || pFileIn == NULL) {
|
||||
return 0;
|
||||
|
@ -824,6 +1026,167 @@ int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, in
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif // WINDOWS
|
||||
|
||||
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
||||
FILE *fp = NULL;
|
||||
#ifdef WINDOWS
|
||||
HANDLE hFile = NULL;
|
||||
#else
|
||||
int fd = -1;
|
||||
#endif
|
||||
if (tdFileOptions & TD_FILE_STREAM) {
|
||||
fp = taosOpenFileForStream(path, tdFileOptions);
|
||||
if (fp == NULL) return NULL;
|
||||
} else {
|
||||
#ifdef WINDOWS
|
||||
hFile = taosOpenFileNotStream(path, tdFileOptions);
|
||||
if (hFile == INVALID_HANDLE_VALUE) return NULL;
|
||||
#else
|
||||
fd = taosOpenFileNotStream(path, tdFileOptions);
|
||||
if (fd == -1) return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
TdFilePtr pFile = (TdFilePtr)taosMemoryMalloc(sizeof(TdFile));
|
||||
if (pFile == NULL) {
|
||||
#ifdef WINDOWS
|
||||
if (hFile != NULL) CloseHandle(hFile);
|
||||
#else
|
||||
if (fd >= 0) close(fd);
|
||||
#endif
|
||||
if (fp != NULL) fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockInit(&(pFile->rwlock), NULL);
|
||||
#endif
|
||||
pFile->fp = fp;
|
||||
pFile->refId = 0;
|
||||
|
||||
#ifdef WINDOWS
|
||||
pFile->hFile = hFile;
|
||||
pFile->tdFileOptions = tdFileOptions;
|
||||
// do nothing, since the property of pmode is set with _O_TEMPORARY; the OS will recycle
|
||||
// the file handle, as well as the space on disk.
|
||||
#else
|
||||
pFile->fd = fd;
|
||||
// Remove it instantly, so when the program exits normally/abnormally, the file
|
||||
// will be automatically remove by OS.
|
||||
if (tdFileOptions & TD_FILE_AUTO_DEL) {
|
||||
unlink(path);
|
||||
}
|
||||
#endif
|
||||
return pFile;
|
||||
}
|
||||
|
||||
int32_t taosCloseFile(TdFilePtr *ppFile) {
|
||||
int32_t code = 0;
|
||||
if (ppFile == NULL || *ppFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockWrlock(&((*ppFile)->rwlock));
|
||||
#endif
|
||||
if ((*ppFile)->fp != NULL) {
|
||||
fflush((*ppFile)->fp);
|
||||
fclose((*ppFile)->fp);
|
||||
(*ppFile)->fp = NULL;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
if ((*ppFile)->hFile != NULL) {
|
||||
// FlushFileBuffers((*ppFile)->hFile);
|
||||
if (!CloseHandle((*ppFile)->hFile)) {
|
||||
code = -1;
|
||||
}
|
||||
(*ppFile)->hFile = NULL;
|
||||
#else
|
||||
if ((*ppFile)->fd >= 0) {
|
||||
// warning: never fsync silently in base lib
|
||||
/*fsync((*ppFile)->fd);*/
|
||||
code = close((*ppFile)->fd);
|
||||
(*ppFile)->fd = -1;
|
||||
#endif
|
||||
}
|
||||
(*ppFile)->refId = 0;
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&((*ppFile)->rwlock));
|
||||
taosThreadRwlockDestroy(&((*ppFile)->rwlock));
|
||||
#endif
|
||||
taosMemoryFree(*ppFile);
|
||||
*ppFile = NULL;
|
||||
return code;
|
||||
}
|
||||
|
||||
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockRdlock(&(pFile->rwlock));
|
||||
#endif
|
||||
ASSERT(pFile->hFile != NULL); // Please check if you have closed the file.
|
||||
if (pFile->hFile == NULL) {
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
DWORD ret = 0;
|
||||
OVERLAPPED ol = {0};
|
||||
ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
|
||||
ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
|
||||
|
||||
SetLastError(0);
|
||||
BOOL result = ReadFile(pFile->hFile, buf, count, &ret, &ol);
|
||||
if (!result && GetLastError() != ERROR_HANDLE_EOF) {
|
||||
errno = GetLastError();
|
||||
ret = -1;
|
||||
}
|
||||
#else
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockRdlock(&(pFile->rwlock));
|
||||
#endif
|
||||
ASSERT(pFile->fd >= 0); // Please check if you have closed the file.
|
||||
if (pFile->fd < 0) {
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
int64_t ret = pread(pFile->fd, buf, count, offset);
|
||||
#endif
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t taosFsyncFile(TdFilePtr pFile) {
|
||||
if (pFile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this implementation is WRONG
|
||||
// fflush is not a replacement of fsync
|
||||
if (pFile->fp != NULL) return fflush(pFile->fp);
|
||||
#ifdef WINDOWS
|
||||
if (pFile->hFile != NULL) {
|
||||
if (pFile->tdFileOptions & TD_FILE_WRITE_THROUGH) {
|
||||
return 0;
|
||||
}
|
||||
return !FlushFileBuffers(pFile->hFile);
|
||||
#else
|
||||
if (pFile->fd >= 0) {
|
||||
return fsync(pFile->fd);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void taosFprintfFile(TdFilePtr pFile, const char *format, ...) {
|
||||
if (pFile == NULL || pFile->fp == NULL) {
|
||||
return;
|
||||
|
@ -834,7 +1197,13 @@ void taosFprintfFile(TdFilePtr pFile, const char *format, ...) {
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
bool taosValidFile(TdFilePtr pFile) { return pFile != NULL && pFile->fd > 0; }
|
||||
bool taosValidFile(TdFilePtr pFile) {
|
||||
#ifdef WINDOWS
|
||||
return pFile != NULL && pFile->hFile != NULL;
|
||||
#else
|
||||
return pFile != NULL && pFile->fd > 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t taosUmaskFile(int32_t maskVal) {
|
||||
#ifdef WINDOWS
|
||||
|
@ -960,14 +1329,20 @@ int32_t taosCompressFile(char *srcFileName, char *destFileName) {
|
|||
goto cmp_end;
|
||||
}
|
||||
|
||||
pFile = taosOpenFile(destFileName, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
if (pFile == NULL) {
|
||||
int access = O_BINARY | O_WRONLY | O_TRUNC | O_CREAT;
|
||||
#ifdef WINDOWS
|
||||
int32_t pmode = _S_IREAD | _S_IWRITE;
|
||||
#else
|
||||
int32_t pmode = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
#endif
|
||||
int fd = open(destFileName, access, pmode);
|
||||
if (fd < 0) {
|
||||
ret = -2;
|
||||
goto cmp_end;
|
||||
}
|
||||
|
||||
// Both gzclose() and fclose() will close the associated fd, so they need to have different fds.
|
||||
FileFd gzFd = dup(pFile->fd);
|
||||
FileFd gzFd = dup(fd);
|
||||
if (gzFd < 0) {
|
||||
ret = -4;
|
||||
goto cmp_end;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
@ -29,6 +30,10 @@
|
|||
#include "os.h"
|
||||
#include "tlog.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include <windows.h>
|
||||
#endif // WINDOWS
|
||||
|
||||
TEST(osTest, osSystem) {
|
||||
const char *flags = "UTL FATAL ";
|
||||
ELogLevel level = DEBUG_FATAL;
|
||||
|
@ -68,7 +73,8 @@ void fileOperateOnBusy(void *param) {
|
|||
char * fname = (char *)param;
|
||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
|
||||
printf("On busy thread open file\n");
|
||||
ASSERT_NE(pFile, nullptr);
|
||||
if (pFile == NULL) return;
|
||||
// ASSERT_NE(pFile, nullptr);
|
||||
|
||||
int ret = taosLockFile(pFile);
|
||||
printf("On busy thread lock file ret:%d\n", ret);
|
||||
|
@ -97,6 +103,7 @@ TEST(osTest, osFile) {
|
|||
TdFilePtr pOutFD = taosCreateFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
|
||||
ASSERT_NE(pOutFD, nullptr);
|
||||
printf("create file success\n");
|
||||
taosCloseFile(&pOutFD);
|
||||
|
||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
|
||||
printf("open file\n");
|
||||
|
@ -135,4 +142,178 @@ TEST(osTest, osFile) {
|
|||
//printf("remove file success");
|
||||
}
|
||||
|
||||
#ifndef OSFILE_PERFORMANCE_TEST
|
||||
|
||||
#define MAX_WORDS 100
|
||||
#define MAX_WORD_LENGTH 20
|
||||
#define MAX_TEST_FILE_SIZE 100000
|
||||
#define TESTTIMES 1000
|
||||
|
||||
char *getRandomWord() {
|
||||
static char words[][MAX_WORD_LENGTH] = {
|
||||
"Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
|
||||
"sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna",
|
||||
"aliqua", "Ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", "exercitation", "ullamco",
|
||||
"Why", "do", "programmers", "prefer", "using", "dark", "mode?", "Because", "light", "attracts",
|
||||
"bugs", "and", "they", "want", "to", "code", "in", "peace,", "like", "a", "ninja", "in", "the", "shadows."
|
||||
"aliqua", "Ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", "exercitation", "ullamco",
|
||||
"laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", "consequat", "Duis", "aute", "irure",
|
||||
"dolor", "in", "reprehenderit", "in", "voluptate", "velit", "esse", "cillum", "dolore", "eu",
|
||||
"fugiat", "nulla", "pariatur", "Excepteur", "sint", "occaecat", "cupidatat", "non", "proident",
|
||||
"sunt", "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum"
|
||||
};
|
||||
|
||||
return words[taosRand() % MAX_WORDS];
|
||||
}
|
||||
|
||||
int64_t fillBufferWithRandomWords(char *buffer, int64_t maxBufferSize) {
|
||||
int64_t len = 0;
|
||||
while (len < maxBufferSize) {
|
||||
char * word = getRandomWord();
|
||||
size_t wordLen = strlen(word);
|
||||
|
||||
if (len + wordLen + 1 < maxBufferSize) {
|
||||
strcat(buffer, word);
|
||||
strcat(buffer, " ");
|
||||
len += wordLen + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int64_t calculateAverage(int64_t arr[], int size) {
|
||||
int64_t sum = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
sum += arr[i];
|
||||
}
|
||||
return sum / size;
|
||||
}
|
||||
|
||||
int64_t calculateMax(int64_t arr[], int size) {
|
||||
int64_t max = arr[0];
|
||||
for (int i = 1; i < size; i++) {
|
||||
if (arr[i] > max) {
|
||||
max = arr[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
int64_t calculateMin(int64_t arr[], int size) {
|
||||
int64_t min = arr[0];
|
||||
for (int i = 1; i < size; i++) {
|
||||
if (arr[i] < min) {
|
||||
min = arr[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
TEST(osTest, osFilePerformance) {
|
||||
printf("os file performance testting...\n");
|
||||
int64_t WriteFileCost;
|
||||
int64_t ReadFileCost;
|
||||
int64_t OpenForWriteCloseFileCost;
|
||||
int64_t OpenForReadCloseFileCost;
|
||||
|
||||
char * buffer;
|
||||
char * writeBuffer = (char *)taosMemoryCalloc(1, MAX_TEST_FILE_SIZE);
|
||||
char * readBuffer = (char *)taosMemoryCalloc(1, MAX_TEST_FILE_SIZE);
|
||||
int64_t size = fillBufferWithRandomWords(writeBuffer, MAX_TEST_FILE_SIZE);
|
||||
char * fname = "./osFilePerformanceTest.txt";
|
||||
|
||||
TdFilePtr pOutFD = taosCreateFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
|
||||
ASSERT_NE(pOutFD, nullptr);
|
||||
taosCloseFile(&pOutFD);
|
||||
|
||||
printf("os file performance start write...\n");
|
||||
int64_t t1 = taosGetTimestampUs();
|
||||
for (int i = 0; i < TESTTIMES; ++i) {
|
||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_WRITE_THROUGH);
|
||||
ASSERT_NE(pFile, nullptr);
|
||||
taosWriteFile(pFile, writeBuffer, size);
|
||||
taosFsyncFile(pFile);
|
||||
taosCloseFile(&pFile);
|
||||
}
|
||||
|
||||
int64_t t2 = taosGetTimestampUs();
|
||||
WriteFileCost = t2 - t1;
|
||||
|
||||
printf("os file performance start read...\n");
|
||||
for (int i = 0; i < TESTTIMES; ++i) {
|
||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ);
|
||||
ASSERT_NE(pFile, nullptr);
|
||||
taosReadFile(pFile, readBuffer, size);
|
||||
taosCloseFile(&pFile);
|
||||
int readLine = strlen(readBuffer);
|
||||
ASSERT_EQ(size, readLine);
|
||||
}
|
||||
int64_t t3 = taosGetTimestampUs();
|
||||
ReadFileCost = t3 - t2;
|
||||
|
||||
printf("os file performance start open1...\n");
|
||||
for (int i = 0; i < TESTTIMES; ++i) {
|
||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_WRITE);
|
||||
ASSERT_NE(pFile, nullptr);
|
||||
taosCloseFile(&pFile);
|
||||
}
|
||||
int64_t t4 = taosGetTimestampUs();
|
||||
OpenForWriteCloseFileCost = t4 - t3;
|
||||
|
||||
printf("os file performance start open2...\n");
|
||||
for (int i = 0; i < TESTTIMES; ++i) {
|
||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_CREATE | TD_FILE_READ);
|
||||
ASSERT_NE(pFile, nullptr);
|
||||
taosCloseFile(&pFile);
|
||||
}
|
||||
int64_t t5 = taosGetTimestampUs();
|
||||
OpenForReadCloseFileCost = t5 - t4;
|
||||
|
||||
#ifdef WINDOWS
|
||||
printf("os file performance start window native...\n");
|
||||
for (int i = 0; i < TESTTIMES; ++i) {
|
||||
HANDLE hFile = CreateFile(fname, // 文件名
|
||||
GENERIC_WRITE, // 写权限
|
||||
FILE_SHARE_READ, // 不共享
|
||||
NULL, // 默认安全描述符
|
||||
OPEN_ALWAYS, // 打开已存在的文件
|
||||
FILE_FLAG_WRITE_THROUGH, // 文件标志,可以根据实际需求调整
|
||||
NULL // 模板文件句柄,对于创建新文件不需要
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
printf("Error opening file\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// 写入数据
|
||||
DWORD bytesWritten;
|
||||
if (!WriteFile(hFile, writeBuffer, size, &bytesWritten, NULL)) {
|
||||
// 处理错误
|
||||
printf("Error writing to file\n");
|
||||
CloseHandle(hFile);
|
||||
break;
|
||||
}
|
||||
// 关闭文件
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
int64_t t6 = taosGetTimestampUs();
|
||||
int64_t nativeWritCost = t6 - t5;
|
||||
|
||||
printf("Test Write file using native API %d times, cost: %" PRId64 "us\n", TESTTIMES, nativeWritCost);
|
||||
#endif // WINDOWS
|
||||
|
||||
taosMemoryFree(writeBuffer);
|
||||
taosMemoryFree(readBuffer);
|
||||
|
||||
printf("Test Write file %d times, cost: %" PRId64 "us\n", TESTTIMES, WriteFileCost);
|
||||
printf("Test Read file %d times, cost: %" PRId64 "us\n", TESTTIMES, ReadFileCost);
|
||||
printf("Test OpenForWrite & Close file %d times, cost: %" PRId64 "us\n", TESTTIMES, OpenForWriteCloseFileCost);
|
||||
printf("Test OpenForRead & Close file %d times, cost: %" PRId64 "us\n", TESTTIMES, OpenForReadCloseFileCost);
|
||||
}
|
||||
|
||||
#endif OSFILE_PERFORMANCE_TEST
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -154,7 +154,12 @@ int32_t taosInitSlowLog() {
|
|||
#endif
|
||||
|
||||
if (strlen(tsLogDir) != 0) {
|
||||
char lastC = tsLogDir[strlen(tsLogDir) - 1];
|
||||
if (lastC == '\\' || lastC == '/') {
|
||||
snprintf(fullName, PATH_MAX, "%s" "%s", tsLogDir, logFileName);
|
||||
} else {
|
||||
snprintf(fullName, PATH_MAX, "%s" TD_DIRSEP "%s", tsLogDir, logFileName);
|
||||
}
|
||||
} else {
|
||||
snprintf(fullName, PATH_MAX, "%s", logFileName);
|
||||
}
|
||||
|
@ -178,7 +183,12 @@ int32_t taosInitLog(const char *logName, int32_t maxFiles) {
|
|||
|
||||
char fullName[PATH_MAX] = {0};
|
||||
if (strlen(tsLogDir) != 0) {
|
||||
char lastC = tsLogDir[strlen(tsLogDir) - 1];
|
||||
if (lastC == '\\' || lastC == '/') {
|
||||
snprintf(fullName, PATH_MAX, "%s" "%s", tsLogDir, logName);
|
||||
} else {
|
||||
snprintf(fullName, PATH_MAX, "%s" TD_DIRSEP "%s", tsLogDir, logName);
|
||||
}
|
||||
} else {
|
||||
snprintf(fullName, PATH_MAX, "%s", logName);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue