浏览代码

Z991239-385 #comment 注释 fcntl的记录锁,使用fclock来实现锁

gifur 5 年之前
父节点
当前提交
e684f056c1
共有 2 个文件被更改,包括 60 次插入33 次删除
  1. 30 12
      winpr/libwinpr/utils/ini.c
  2. 30 21
      winpr/libwinpr/utils/test/TestIniMultiProcess.c

+ 30 - 12
winpr/libwinpr/utils/ini.c

@@ -39,6 +39,8 @@
 #include "../log.h"
 #define TAG WINPR_TAG("ini")
 
+//#define TEST_MODE_FOR_INI
+
 struct _wIniFileKey
 {
 	char* name;
@@ -74,6 +76,14 @@ struct _wIniFile
 	wIniFileSection** sections;
 };
 
+static BOOL PathFileExistsA(LPCSTR pszPath)
+{
+	struct stat stat_info;
+	if (stat(pszPath, &stat_info) != 0)
+		return FALSE;
+	return TRUE;
+}
+
 static int IniFile_WriteBackFile(wIniFile* ini);
 
 static BOOL IniFile_Load_NextLine(wIniFile* ini, char* str)
@@ -187,7 +197,6 @@ static BOOL IniFile_Open_File(wIniFile* ini, const char* filename)
 static BOOL IniFile_Load_File(wIniFile* ini, const char* filename)
 {
 	INT64 fileSize;
-	INT64 readSize;
 
 	if (!IniFile_Open_File(ini, filename))
 		return FALSE;
@@ -217,7 +226,7 @@ static BOOL IniFile_Load_File(wIniFile* ini, const char* filename)
 
 		WLog_DBG(TAG, "read content size: %d", fileSize);
 		if (fread(ini->buffer, (size_t)fileSize, 1, ini->fp) != 1) {
-			WLog_ERR(TAG, "read file content failed: %d, %d", readSize, errno);
+			WLog_ERR(TAG, "read file content failed: %d", errno);
 			goto out_buffer;
 		}
 
@@ -985,8 +994,6 @@ WINPR_API BOOL IniFile_Lock(wIniFile* ini)
 
 #ifndef _WIN32
 
-
-	int r;
 	struct flock lock;
 
 	if (ini->writeMode)
@@ -1007,6 +1014,8 @@ WINPR_API BOOL IniFile_Lock(wIniFile* ini)
 		WLog_DBG(TAG, "after flock.");
 	} while (0);
 
+	/*使用 fcntl 不能阻止线程间的冲突,因为锁会覆盖*/
+#if 0
 	do 
 	{
 		/*judge it has lock at the same process*/
@@ -1053,8 +1062,8 @@ WINPR_API BOOL IniFile_Lock(wIniFile* ini)
 			WLog_ERR(TAG, "set %s lock with fcntl(2) failed: %d", ini->writeMode ? "write" : "read", errno);
 			return FALSE;
 		}
-
 	} while (0);
+#endif
 
 #endif //NOT _WIN32
 
@@ -1072,6 +1081,8 @@ WINPR_API void IniFile_Unlock(wIniFile* ini)
 
 		WLog_DBG(TAG, "unlock %s lock.", ini->writeMode ? "write" : "read");
 
+#if 0
+
 		/*when close fd, the record lock would release auto.*/
 		int r;
 		struct flock lock;
@@ -1092,6 +1103,8 @@ WINPR_API void IniFile_Unlock(wIniFile* ini)
 			WLog_ERR(TAG, "flock(LOCK_UN) on %s failed with %d", ini->filename, errno);
 		}
 
+#endif
+
 		fclose(ini->fp);
 		ini->fp = NULL;
 	}
@@ -1265,8 +1278,12 @@ UINT GetPrivateProfileIntA(LPCSTR lpAppName, LPCSTR lpKeyName, INT nDefault, LPC
 		WLog_ERR(TAG, "%s: failed to parse %s", __FUNCTION__, lpFileName);
 		return ret;
 	}
-	//WLog_DBG(TAG, "sleep a little");
-	//Sleep(2000);
+
+#ifdef TEST_MODE_FOR_INI
+	WLog_DBG(TAG, "sleep a little");
+	Sleep(2000);
+#endif // TEST_MODE_FOR_INI
+
 	ret = IniFile_GetKeyValueInt(ini, lpAppName, lpKeyName, nDefault);
 	IniFile_Free(ini);
 
@@ -1390,12 +1407,14 @@ BOOL WritePrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpStr
 		}
 	}
 
-finished:
-
 	if(ret && changed)
 	{
-		//WLog_DBG(TAG, "sleep a little to write.");
-		//Sleep(5000);
+
+#ifdef TEST_MODE_FOR_INI
+		WLog_DBG(TAG, "sleep a little to write.");
+		Sleep(5000);
+#endif // TEST_MODE_FOR_INI
+
 		if (IniFile_WriteBackFile(ini) < 0) {
 			ret = FALSE;
 		}
@@ -1420,7 +1439,6 @@ BOOL WritePrivateProfileSectionA(LPCSTR lpAppName, LPCSTR lpString, LPCSTR lpFil
 	wIniFileSection* pSection = NULL;
 	wIniFileKey* pKey = NULL;
 	char* curToken = NULL;
-	char* nextToken = NULL;
 	char* newKey = NULL;
 	char* newValue = NULL;
 	char* newString = NULL;

+ 30 - 21
winpr/libwinpr/utils/test/TestIniMultiProcess.c

@@ -132,30 +132,39 @@ const int max_thread = 50;
 
 int main(int argc, char* argv[])
 {
-	if (false) {
-		int i;
-		HANDLE threads[max_thread];
-		for (i = 0; i < max_thread; ++i) {
-			threads[i] = CreateThread(NULL, 0, thread_func, NULL, 0, NULL);
-			if (threads[i] == INVALID_HANDLE_VALUE) {
-				fprintf(stderr, "Got an invalid thread!\n");
-				return -1;
+	if (argc == 1) {
+		viceAll();
+	}
+	else if (argc > 1) {
+		if (argv[1][0] == '1') {
+			viceWrite(NULL);
+		}
+		else if (argv[1][0] == '2') {
+			viceRead(NULL);
+		}
+		else if (argv[1][0] == '3') {
+			HANDLE t[3];
+			t[0] = CreateThread(NULL, 0, viceWrite, NULL, 0, NULL);
+			t[1] = CreateThread(NULL, 0, viceRead, NULL, 0, NULL);
+			t[2] = CreateThread(NULL, 0, viceRead, NULL, 0, NULL);
+
+			printf("wait write-read thread done!\n");
+			WaitForMultipleObjects(3, t, TRUE, INFINITE);
+		}
+		else if (argv[1][0] == '4') {
+			int i;
+			HANDLE threads[max_thread];
+			for (i = 0; i < max_thread; ++i) {
+				threads[i] = CreateThread(NULL, 0, thread_func, NULL, 0, NULL);
+				if (threads[i] == INVALID_HANDLE_VALUE) {
+					fprintf(stderr, "Got an invalid thread!\n");
+					return -1;
+				}
 			}
+			WaitForMultipleObjects(max_thread, threads, TRUE, INFINITE);
+			printf("wait all thread done!\n");
 		}
-		printf("wait all thread done!\n");
-		WaitForMultipleObjects(max_thread, threads, TRUE, INFINITE);
 	}
-
-	if (TRUE) 		{
-		HANDLE t[3];
-		t[0] = CreateThread(NULL, 0, viceWrite, NULL, 0, NULL);
-		t[1] = CreateThread(NULL, 0, viceRead, NULL, 0, NULL);
-		t[2] = CreateThread(NULL, 0, viceRead, NULL, 0, NULL);
-
-		printf("wait write-read thread done!\n");
-		WaitForMultipleObjects(3, t, TRUE, INFINITE);
-	}
-
 	printf("exit\n");
 	return 0;
 }