mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Simplify bulk_get_filesystem
Only release python GIL while waiting for messages
This commit is contained in:
parent
93ee37c872
commit
ddc405a337
@ -12,7 +12,7 @@
|
|||||||
namespace wpd {
|
namespace wpd {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_pump_waiting_messages() {
|
pump_waiting_messages() {
|
||||||
UINT firstMsg = 0, lastMsg = 0;
|
UINT firstMsg = 0, lastMsg = 0;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -153,12 +153,8 @@ private:
|
|||||||
unsigned int level;
|
unsigned int level;
|
||||||
HANDLE complete;
|
HANDLE complete;
|
||||||
ULONG self_ref;
|
ULONG self_ref;
|
||||||
PyThreadState *thread_state;
|
|
||||||
PyObject *callback;
|
PyObject *callback;
|
||||||
|
|
||||||
void release_python_gil() { if (thread_state == NULL) thread_state = PyEval_SaveThread(); }
|
|
||||||
void acquire_python_gil() { PyEval_RestoreThread(thread_state); thread_state = NULL; }
|
|
||||||
|
|
||||||
void do_one_object(CComPtr<IPortableDeviceValues> &properties) {
|
void do_one_object(CComPtr<IPortableDeviceValues> &properties) {
|
||||||
com_wchar_raii property;
|
com_wchar_raii property;
|
||||||
if (!SUCCEEDED(properties->GetStringValue(WPD_OBJECT_ID, property.unsafe_address()))) return;
|
if (!SUCCEEDED(properties->GetStringValue(WPD_OBJECT_ID, property.unsafe_address()))) return;
|
||||||
@ -183,19 +179,15 @@ private:
|
|||||||
DWORD num = 0;
|
DWORD num = 0;
|
||||||
if (!items) return;
|
if (!items) return;
|
||||||
if (!SUCCEEDED(values->GetCount(&num))) return;
|
if (!SUCCEEDED(values->GetCount(&num))) return;
|
||||||
acquire_python_gil();
|
|
||||||
|
|
||||||
for (DWORD i = 0; i < num; i++) {
|
for (DWORD i = 0; i < num; i++) {
|
||||||
CComPtr<IPortableDeviceValues> properties;
|
CComPtr<IPortableDeviceValues> properties;
|
||||||
if (SUCCEEDED(values->GetAt(i, &properties))) do_one_object(properties);
|
if (SUCCEEDED(values->GetAt(i, &properties))) do_one_object(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_python_gil();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GetBulkPropertiesCallback() : items(NULL), subfolders(NULL), level(0), complete(INVALID_HANDLE_VALUE), self_ref(0), thread_state(NULL), callback(NULL) {}
|
GetBulkPropertiesCallback() : items(NULL), subfolders(NULL), level(0), complete(INVALID_HANDLE_VALUE), self_ref(0), callback(NULL) {}
|
||||||
~GetBulkPropertiesCallback() { if (complete != INVALID_HANDLE_VALUE) CloseHandle(complete); complete = INVALID_HANDLE_VALUE; }
|
~GetBulkPropertiesCallback() { if (complete != INVALID_HANDLE_VALUE) CloseHandle(complete); complete = INVALID_HANDLE_VALUE; }
|
||||||
|
|
||||||
bool start_processing(PyObject *items, PyObject *subfolders, unsigned int level, PyObject *callback) {
|
bool start_processing(PyObject *items, PyObject *subfolders, unsigned int level, PyObject *callback) {
|
||||||
@ -208,7 +200,7 @@ public:
|
|||||||
}
|
}
|
||||||
void end_processing() {
|
void end_processing() {
|
||||||
if (complete != INVALID_HANDLE_VALUE) CloseHandle(complete);
|
if (complete != INVALID_HANDLE_VALUE) CloseHandle(complete);
|
||||||
items = NULL; subfolders = NULL; level = 0; complete = INVALID_HANDLE_VALUE; callback = NULL; thread_state = NULL;
|
items = NULL; subfolders = NULL; level = 0; complete = INVALID_HANDLE_VALUE; callback = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall OnStart(REFGUID Context) { return S_OK; }
|
HRESULT __stdcall OnStart(REFGUID Context) { return S_OK; }
|
||||||
@ -239,18 +231,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
DWORD wait_for_messages(int seconds=60) {
|
DWORD wait_for_messages(int seconds=60) {
|
||||||
release_python_gil();
|
DWORD wait_result;
|
||||||
DWORD wait_result = MsgWaitForMultipleObjects(1, &complete, FALSE, seconds * 1000, QS_ALLEVENTS);
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
acquire_python_gil();
|
wait_result = MsgWaitForMultipleObjects(1, &complete, FALSE, seconds * 1000, QS_ALLEVENTS);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
return wait_result;
|
return wait_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pump_waiting_messages() {
|
|
||||||
release_python_gil();
|
|
||||||
int pump_result = _pump_waiting_messages();
|
|
||||||
acquire_python_gil();
|
|
||||||
return pump_result;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -291,11 +278,10 @@ bulk_get_filesystem(
|
|||||||
|
|
||||||
while (!PyErr_Occurred()) {
|
while (!PyErr_Occurred()) {
|
||||||
DWORD wait_result = bulk_properties_callback->wait_for_messages();
|
DWORD wait_result = bulk_properties_callback->wait_for_messages();
|
||||||
|
|
||||||
if (wait_result == WAIT_OBJECT_0) {
|
if (wait_result == WAIT_OBJECT_0) {
|
||||||
break; // Event was signalled, bulk operation complete
|
break; // Event was signalled, bulk operation complete
|
||||||
} else if (wait_result == WAIT_OBJECT_0 + 1) { // Messages need to be dispatched
|
} else if (wait_result == WAIT_OBJECT_0 + 1) { // Messages need to be dispatched
|
||||||
int pump_result = bulk_properties_callback->pump_waiting_messages();
|
int pump_result = pump_waiting_messages();
|
||||||
if (pump_result == 1) PyErr_SetString(PyExc_RuntimeError, "Application has been asked to quit.");
|
if (pump_result == 1) PyErr_SetString(PyExc_RuntimeError, "Application has been asked to quit.");
|
||||||
} else if (wait_result == WAIT_TIMEOUT) {
|
} else if (wait_result == WAIT_TIMEOUT) {
|
||||||
// 60 seconds with no updates, looks bad
|
// 60 seconds with no updates, looks bad
|
||||||
@ -311,7 +297,7 @@ bulk_get_filesystem(
|
|||||||
bulk_properties_callback->end_processing();
|
bulk_properties_callback->end_processing();
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
bulk_properties->Cancel(guid_context);
|
bulk_properties->Cancel(guid_context);
|
||||||
bulk_properties_callback->pump_waiting_messages();
|
pump_waiting_messages();
|
||||||
}
|
}
|
||||||
return PyErr_Occurred() ? false : true;
|
return PyErr_Occurred() ? false : true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user