Windows API - GetLastError woes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Windows API - GetLastError woes

Esa Ilari Vuokko

Hi,

My "use case" is in Win32-package, where we simply call a FFI
imported call and on failures call GetLastError to get extended
error code.  GetLastError of course only works on same OS thread
and contains sensible results only before next Windows API call.
It's much like C/posix errno.

So, we *must* call GetLastError in the same OS thread, and there
must not be any Windows API calls in between, including those caused
by, say, rts' memory allocation or calls to lock mutexes.  Unless the
error code is saved via Get/SetLastError.

Also, I'd like not to run the code in a another OS thread (and
that won't fix the rts-caused Windows API calls), because the calls
are supposed to be fast, and OS-level context switch isn't fast.

Is this problem real, or did I miss some magic feature of rts?

The only way to solve this problem seems to be to wrap all
calls in C-functions that take care of reading GetLastError.
Not that it's impossible, just very annoying.

Best regards,
--Esa Ilari Vuokko
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Windows API - GetLastError woes

Brian Hulley
Esa Ilari Vuokko wrote:

> Hi,
>
> My "use case" is in Win32-package, where we simply call a FFI
> imported call and on failures call GetLastError to get extended
> error code.  GetLastError of course only works on same OS thread
> and contains sensible results only before next Windows API call.
> It's much like C/posix errno.
>
> So, we *must* call GetLastError in the same OS thread, and there
> must not be any Windows API calls in between, including those caused
> by, say, rts' memory allocation or calls to lock mutexes.  Unless the
> error code is saved via Get/SetLastError.
>
> Also, I'd like not to run the code in a another OS thread (and
> that won't fix the rts-caused Windows API calls), because the calls
> are supposed to be fast, and OS-level context switch isn't fast.
>
> Is this problem real, or did I miss some magic feature of rts?
>
> The only way to solve this problem seems to be to wrap all
> calls in C-functions that take care of reading GetLastError.
> Not that it's impossible, just very annoying.

If there is no better solution, would it be possible on failure to somehow
enter a critical section and repeat the call that caused the failure and
then call get last error and exit the critical section so that normal calls
would be fast but only failed calls would be slow?

Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Windows API - GetLastError woes

Esa Ilari Vuokko

Brian Hulley wrote:
>> The only way to solve this problem seems to be to wrap all
>> calls in C-functions that take care of reading GetLastError.
>> Not that it's impossible, just very annoying.
>
> If there is no better solution, would it be possible on failure to
> somehow enter a critical section and repeat the call that caused the
> failure and then call get last error and exit the critical section so
> that normal calls would be fast but only failed calls would be slow?

In some (many) cases, yes, but for example with async IO you really
don't want to do this.  Some "errors" still cause async notification.

Gut instinct tells me repeating system calls might also cause atomicity
issues, but I don't have an example.

Best regards,
--Esa
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Windows API - GetLastError woes

Neil Mitchell
In reply to this post by Brian Hulley
Hi

> If there is no better solution, would it be possible on failure to somehow
> enter a critical section and repeat the call that caused the failure and
> then call get last error and exit the critical section so that normal calls
> would be fast but only failed calls would be slow?

No. This isn't Haskell - this is the Windows API. Some functions i.e.
DeleteFile might fail differently different times round, plus you
could cause unimaginable damage by arbitrarily redoing certain
actions.

It might be safe for some subset of commands, but I'd be vary wary
about specifying that subset. Getting it wrong is going to cause a lot
of pain.

Thanks

Neil
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Windows API - GetLastError woes

Simon Marlow-5
In reply to this post by Esa Ilari Vuokko
Esa Ilari Vuokko wrote:

> My "use case" is in Win32-package, where we simply call a FFI
> imported call and on failures call GetLastError to get extended
> error code.  GetLastError of course only works on same OS thread
> and contains sensible results only before next Windows API call.
> It's much like C/posix errno.
>
> So, we *must* call GetLastError in the same OS thread, and there
> must not be any Windows API calls in between, including those caused
> by, say, rts' memory allocation or calls to lock mutexes.  Unless the
> error code is saved via Get/SetLastError.
>
> Also, I'd like not to run the code in a another OS thread (and
> that won't fix the rts-caused Windows API calls), because the calls
> are supposed to be fast, and OS-level context switch isn't fast.
>
> Is this problem real, or did I miss some magic feature of rts?

This is most definitely a real problem.  On Unix we have some hacks to make
errno thread-local: basically we store it in the thread state object for the
Haskell thread, and make sure we save/restore it around any RTS operations that
might affect it.

We need to do the same tricks on Windows using GetLastError/SetLastError, it
shouldn't be too difficult.  Would you like to submit a ticket?

Cheers,
        Simon
_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users