aguinet / dragonffi

C Foreign Function Interface and JIT using Clang/LLVM
Apache License 2.0
548 stars 23 forks source link

Preserving the last error. #62

Closed neitsa closed 3 years ago

neitsa commented 3 years ago

Hi Adrien :)

Would it be difficult to have a mechanism for preserving the "last error" for different systems / runtimes?

For example the Windows API relies heavily on APIs returning a NULL / FALSE / 0 / -1 value on error. So if anything went wrong while calling an API, the developer must use the GetLastError API to know what went really wrong and decide accordingly on how to handle the error. The "last error" (which is per-thread on Windows) is overridden almost every time an API is called (this also includes system calls).

Obviously a similar system is also used for errno.

While using dragonffi there's no guarantee that this "last error" has been preserved, so if anything goes wrong it might be difficult for the caller to actually get a sensible feedback from the system / runtime.

ctypes offers an ad hoc mechanism in the form of ctypes.get_last_error for Windows APIs and ctypes.get_errno for errno.

Do you think there's a possibility for such a mechanism to be implemented in dragonffi?

Thanks!

aguinetqb commented 3 years ago

Hello Neitsa :)

That's an interesting problem. I guess a "quick fix" could be done, the question I would have is how much this could be "optimized" so that we don't have a call to GetLastError for every call done by DragonFFI. I will take a look at how ctypes implements this! If you have any information/idea about this, I'm all hears :)

aguinetqb commented 3 years ago

It looks like ctypes has a flag to enable this explicitely. I guess we can do something similar!

neitsa commented 3 years ago

Thank you very much Adrien :+1: ; I'll test by the end of the week!

neitsa commented 3 years ago

Just to keep you informed, I did a test with multiple native threads (using CreateThread Windows API) where each thread would set its last error and none of them seems to have wrongly affected the last error as retrieved by pydffi!

🍾 🥇

aguinet commented 3 years ago

Thanks for the feedback! I think this small thread_local keyword made this work ;) : https://github.com/aguinet/dragonffi/blob/08c394307a37f926d5be42e5a5202a4b3bc16259/lib/dffi_api_win.inc#L12