-
Notifications
You must be signed in to change notification settings - Fork 1
Hydrate file thread safe #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
21bd1ad
819a1f1
cc1b678
444a2d5
b5eff5e
fe31746
32c5ea9
75681d6
205f2be
9648c94
77c59bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,16 +6,21 @@ | |
| #include <string> | ||
|
|
||
| template <typename Fn> | ||
| napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn) { | ||
| napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn, const char* function_name) { | ||
| try { | ||
| return fn(env, info); | ||
| } catch (const std::exception& e) { | ||
| napi_throw_error(env, nullptr, e.what()); | ||
| std::string error_msg = std::string("[") + function_name + "] " + e.what(); | ||
| napi_throw_error(env, nullptr, error_msg.c_str()); | ||
| } catch (...) { | ||
| napi_throw_error(env, nullptr, "Unknown native error"); | ||
| std::string error_msg = std::string("[") + function_name + "] Unknown native error"; | ||
| napi_throw_error(env, nullptr, error_msg.c_str()); | ||
| } | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| #define NAPI_SAFE_WRAP(env, info, fn) \ | ||
| napi_safe_wrap(env, info, fn, __FUNCTION__) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically we have created this wrapper so we log also the name of the function that is wrapping. Why? This is wrapper that wraps all unexpected C++ exceptions and converts them in a javascript exception ( |
||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,11 +11,6 @@ namespace fs = std::filesystem; | |
| CF_CONNECTION_KEY gloablConnectionKey; | ||
| std::map<std::wstring, CF_CONNECTION_KEY> connectionMap; | ||
|
|
||
| void TransformInputCallbacksToSyncCallbacks(napi_env env, InputSyncCallbacks input) | ||
| { | ||
| register_threadsafe_callbacks(env, input); | ||
| } | ||
|
|
||
| void AddCustomState( | ||
| _In_ winrt::IVector<winrt::StorageProviderItemPropertyDefinition> &customStates, | ||
| _In_ LPCWSTR displayNameResource, | ||
|
|
@@ -257,40 +252,30 @@ HRESULT SyncRoot::UnregisterSyncRoot(const wchar_t *providerIdStr) | |
|
|
||
| HRESULT SyncRoot::ConnectSyncRoot(const wchar_t *syncRootPath, InputSyncCallbacks syncCallbacks, napi_env env, CF_CONNECTION_KEY *connectionKey) | ||
| { | ||
| try | ||
| { | ||
| Utilities::AddFolderToSearchIndexer(syncRootPath); | ||
|
|
||
| TransformInputCallbacksToSyncCallbacks(env, syncCallbacks); | ||
|
|
||
| CF_CALLBACK_REGISTRATION callbackTable[] = { | ||
| {CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper}, | ||
| {CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper}, | ||
| CF_CALLBACK_REGISTRATION_END}; | ||
|
|
||
| HRESULT hr = CfConnectSyncRoot( | ||
| syncRootPath, | ||
| callbackTable, | ||
| nullptr, // Contexto (opcional) | ||
| CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH, | ||
| connectionKey); | ||
| wprintf(L"Connection key: %llu\n", *connectionKey); | ||
| if (SUCCEEDED(hr)) | ||
| { | ||
| connectionMap[syncRootPath] = *connectionKey; | ||
| } | ||
| return hr; | ||
| } | ||
| catch (const std::exception &e) | ||
| { | ||
| wprintf(L"Excepción capturada: %hs\n", e.what()); | ||
| return E_FAIL; | ||
| } | ||
| catch (...) | ||
| { | ||
| wprintf(L"Excepción desconocida capturada\n"); | ||
| return E_FAIL; | ||
| Utilities::AddFolderToSearchIndexer(syncRootPath); | ||
| register_threadsafe_callbacks(env, syncCallbacks); | ||
|
|
||
| CF_CALLBACK_REGISTRATION callbackTable[] = { | ||
| {CF_CALLBACK_TYPE_FETCH_DATA, fetch_data_callback_wrapper}, | ||
| {CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, cancel_fetch_data_callback_wrapper}, | ||
| CF_CALLBACK_REGISTRATION_END | ||
| }; | ||
|
|
||
| HRESULT hr = CfConnectSyncRoot( | ||
| syncRootPath, | ||
| callbackTable, | ||
| nullptr, | ||
| CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH, | ||
| connectionKey | ||
| ); | ||
|
|
||
| wprintf(L"Connection key: %llu\n", connectionKey->Internal); | ||
|
|
||
| if (SUCCEEDED(hr)) { | ||
| connectionMap[syncRootPath] = *connectionKey; | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we have removed the try catch since we already obtaining this using the previous |
||
|
|
||
| return hr; | ||
| } | ||
|
|
||
| // disconection sync root | ||
|
|
@@ -308,50 +293,3 @@ HRESULT SyncRoot::DisconnectSyncRoot(const wchar_t *syncRootPath) | |
| } | ||
| return E_FAIL; | ||
| } | ||
|
|
||
| // struct | ||
| struct FileIdentityInfo | ||
| { | ||
| BYTE *FileIdentity; | ||
| size_t FileIdentityLength; | ||
| }; | ||
|
|
||
| void SyncRoot::DeleteFileSyncRoot(const wchar_t *path) | ||
| { | ||
| try | ||
| { | ||
| // Mostrar el archivo a eliminar | ||
| wprintf(L"Intentando eliminar: %ls\n", path); | ||
|
|
||
| // Verificar si el archivo es un directorio o un archivo regular | ||
| bool isDirectory = fs::is_directory(path); | ||
| wprintf(L"Es directorio: %d\n", isDirectory); | ||
|
|
||
| // Si es un directorio, eliminar recursivamente | ||
| if (isDirectory) | ||
| { | ||
| fs::remove_all(path); // Esta línea reemplaza la función personalizada DeleteFileOrDirectory | ||
| wprintf(L"Directorio eliminado con éxito: %ls\n", path); | ||
| } | ||
| else | ||
| { | ||
| // Si es un archivo, simplemente eliminar | ||
| if (!DeleteFileW(path)) | ||
| { | ||
| wprintf(L"No se pudo eliminar el archivo: %ls\n", path); | ||
| } | ||
| else | ||
| { | ||
| wprintf(L"Archivo eliminado con éxito: %ls\n", path); | ||
| } | ||
| } | ||
| } | ||
| catch (const std::exception &e) | ||
| { | ||
| wprintf(L"Excepción capturada: %hs\n", e.what()); | ||
| } | ||
| catch (...) | ||
| { | ||
| wprintf(L"Excepción desconocida capturada\n"); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,77 +5,39 @@ napi_value connect_sync_root_impl(napi_env env, napi_callback_info args) | |
| { | ||
| size_t argc = 2; | ||
| napi_value argv[2]; | ||
|
|
||
| napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); | ||
|
|
||
| if (argc < 2) | ||
| { | ||
| napi_throw_error(env, nullptr, "Se requieren más argumentos para ConnectSyncRoot"); | ||
| return nullptr; | ||
| } | ||
|
|
||
| LPCWSTR syncRootPath; | ||
| size_t pathLength; | ||
| napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength); | ||
| syncRootPath = new WCHAR[pathLength + 1]; | ||
| napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t *>(const_cast<wchar_t *>(syncRootPath)), pathLength + 1, nullptr); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could lead to a memory leak. |
||
| std::wstring syncRootPath(pathLength, L'\0'); | ||
| napi_get_value_string_utf16(env, argv[0], reinterpret_cast<char16_t*>(&syncRootPath[0]), pathLength + 1, nullptr); | ||
|
|
||
| // CALLBACKS | ||
| InputSyncCallbacks callbacks = {}; | ||
|
|
||
| napi_value fetchDataCallback; | ||
| napi_value cancelFetchDataCallback; | ||
|
|
||
| if (napi_get_named_property(env, argv[1], "fetchDataCallback", &fetchDataCallback) == napi_ok) | ||
| { | ||
| napi_create_reference(env, fetchDataCallback, 1, &callbacks.fetch_data_callback_ref); | ||
| } | ||
|
|
||
| napi_valuetype valuetype_fetch_data; | ||
| napi_status type_status_fetch_data = napi_typeof(env, fetchDataCallback, &valuetype_fetch_data); | ||
| if (type_status_fetch_data != napi_ok || valuetype_fetch_data != napi_function) | ||
| { | ||
| napi_throw_error(env, nullptr, "fetchDataCallback should be a function."); | ||
| return nullptr; | ||
| } | ||
| napi_get_named_property(env, argv[1], "fetchDataCallback", &fetchDataCallback); | ||
| napi_create_reference(env, fetchDataCallback, 1, &callbacks.fetch_data_callback_ref); | ||
|
|
||
| if (napi_get_named_property(env, argv[1], "cancelFetchDataCallback", &cancelFetchDataCallback) == napi_ok) | ||
| { | ||
| napi_create_reference(env, cancelFetchDataCallback, 1, &callbacks.cancel_fetch_data_callback_ref); | ||
| } | ||
|
|
||
| napi_valuetype valuetype_cancel_fetch_data; | ||
| napi_status type_status_cancel_fetch_data = napi_typeof(env, cancelFetchDataCallback, &valuetype_cancel_fetch_data); | ||
| if (type_status_cancel_fetch_data != napi_ok || valuetype_cancel_fetch_data != napi_function) | ||
| { | ||
| napi_throw_error(env, nullptr, "cancelFetchDataCallback should be a function."); | ||
| return nullptr; | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we control the input from javascript we don't need to validate here that we pass functions, otherwise it will break in development and we make this function clearer and simpler. |
||
| napi_value cancelFetchDataCallback; | ||
| napi_get_named_property(env, argv[1], "cancelFetchDataCallback", &cancelFetchDataCallback); | ||
| napi_create_reference(env, cancelFetchDataCallback, 1, &callbacks.cancel_fetch_data_callback_ref); | ||
|
|
||
| CF_CONNECTION_KEY connectionKey; | ||
| HRESULT hr = SyncRoot::ConnectSyncRoot(syncRootPath, callbacks, env, &connectionKey); | ||
| HRESULT hr = SyncRoot::ConnectSyncRoot(syncRootPath.c_str(), callbacks, env, &connectionKey); | ||
|
|
||
| delete[] syncRootPath; | ||
|
|
||
| if (FAILED(hr)) | ||
| { | ||
| if (FAILED(hr)) { | ||
| napi_throw_error(env, nullptr, "ConnectSyncRoot failed"); | ||
| return nullptr; | ||
| } | ||
|
|
||
| napi_value resultObj, hrValue, connectionKeyValue; | ||
|
|
||
| napi_create_object(env, &resultObj); | ||
|
|
||
| napi_create_int32(env, static_cast<int32_t>(hr), &hrValue); | ||
| napi_set_named_property(env, resultObj, "hr", hrValue); | ||
|
|
||
| std::wstringstream ss; | ||
| ss << connectionKey.Internal; | ||
|
|
||
| std::wstring connectionKeyString = ss.str(); | ||
| napi_create_string_utf16(env, reinterpret_cast<const char16_t *>(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue); | ||
|
|
||
| std::wstring connectionKeyString = std::to_wstring(connectionKey.Internal); | ||
| napi_create_string_utf16(env, reinterpret_cast<const char16_t*>(connectionKeyString.c_str()), connectionKeyString.length(), &connectionKeyValue); | ||
| napi_set_named_property(env, resultObj, "connectionKey", connectionKeyValue); | ||
|
|
||
| return resultObj; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not used in javascript so we can remove it.