Simplify the function OPENSSL_isservice#4096
Simplify the function OPENSSL_isservice#4096xiaoyinl wants to merge 4 commits intoopenssl:masterfrom
Conversation
I am not sure why a union is needed here. It seems to me a simple static function pointer variable is OK. Also added a comment to clarify why we want to call the exported function _OPENSSL_isservice.
|
Union here follows a common pattern, which in turn is a recognition of the fact that language standard doesn't guarantee meaningful outcome of cast between pointer to data and pointer to function, or vice versa. Or rather that it's specified to be implementation-defined. Even though direct, union-less cast should work as expected with Win32 compilers, it doesn't actually prohibit them to issue a warning. And even though they don't issue warning, it's not inappropriate to adhere to pattern that is guaranteed to be warning-free. |
.. by using a Boolean variable to flag whether f_isservice has a cached value.
|
@dot-asm Thank you very much for your detailed explanation! Now I see why a union is used here. I pushed another commit. This time I use a flag variable to track whether we have a cached result in the function pointer, which I think is warning-free and probably easier to understand. |
crypto/cryptlib.c
Outdated
| static FARPROC f_isservice = NULL; | ||
| static int is_first_time = 1; | ||
|
|
||
| /* Allow application to override OPENSSL_isservice by exporting |
There was a problem hiding this comment.
style is that the "/*" appears on a line by itself.
crypto/cryptlib.c
Outdated
|
|
||
| if (_OPENSSL_isservice.p == NULL) { | ||
| static FARPROC f_isservice = NULL; | ||
| static int is_first_time = 1; |
There was a problem hiding this comment.
please put the static variables first.
There was a problem hiding this comment.
Both are fixed. Thanks!
|
Allow me to be more explicit. It's firm -1 from me. Suggested alternative is explicitly thread unsafe. One can argue that original is not exactly thread-safe in conventional sense, but it works in practice because value returned by GetProcAddress is constant. Worse that can currently happen is that GetProcAddress is executed twice, while worse that can happen in this merge |
|
I totally overlooked thread safety. Sorry! Now I move |
|
Maybe I am wrong again, but now I feel my latest proposed code is slightly better in thread safety than the original code. For the original one, there is a very tiny possibility that it causes a NULL dereference. It can occur if after thread A sets My proposed code doesn't have this issue because |
|
Right. Compiler can still generate right code, but we may not assume that it does. However! For same reason we may not assume that compiler compiles code that is using two variables, one being kind of synchronization flag, correctly. In other words, having single "self-synchronizing" variable is the only viable approach. Sorry about delay... |
|
I see. Thanks for explanation again! |
|
But you don't want to fix it? I mean there formally is problem, just two variables is not right approach... |
|
But I can't think of a better way to implement it with one variable. |
I am not sure why a union is needed here. It seems to me a simple static function pointer variable is OK.
Also added a comment to clarify why we want to call the exported function
_OPENSSL_isservice.