EXETOOLS FORUM  

Go Back   EXETOOLS FORUM > General > Source Code

Notices

Reply
 
Thread Tools Display Modes
  #31  
Old 04-15-2018, 16:17
bugficks bugficks is offline
Friend
 
Join Date: Apr 2018
Posts: 8
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 2
Thanks Rcvd at 6 Times in 2 Posts
bugficks Reputation: 0
Quote:
Originally Posted by mcp View Post
Data races yield undefined behavior, so the worst thing that could happen is that this code produces hard to find bugs/crashes. There is no such thing as "virtually thread safe"
good luck trying to get it to crash
anyways, this should fix it:
Code:
    static thread_local lib_map libMap;
Quote:
Originally Posted by dosprog View Post
There is such a thing as the portability of the source code.
really? feel free to do so. i ve already posted a highly portable version
Reply With Quote
  #32  
Old 04-15-2018, 18:48
mcp mcp is online now
Friend
 
Join Date: Dec 2011
Posts: 71
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 6
Thanks Rcvd at 17 Times in 9 Posts
mcp Reputation: 12
Well, if the code yields UB, that needs to be fixed since it violates the C++ standard. This code violates assumptions made by the compiler when reasoning about/optimizing your program - I shouldn't have to get your program to crash. Above reasoning should already convince you that this code needs to be fixed.
Also, I would move the caching outside of the function, or simply use a mutex - these are much faster than people usually assume, and always safe.
Reply With Quote
  #33  
Old 04-16-2018, 07:24
bugficks bugficks is offline
Friend
 
Join Date: Apr 2018
Posts: 8
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 2
Thanks Rcvd at 6 Times in 2 Posts
bugficks Reputation: 0
i ve never stated that this is thread safe assuming that it is is wrong.
this snippet is thought as c++ type safe replacement for original post.
i agree its not production code where youd better use some loader/lib/functor classes but thats not the purpose of these few lines and neither is original post. its rather for quick testing and only requiring copy&paste a few lines of code.

fwiw this aint thread safe either:
PHP Code:
    if(!(lib GetModuleHandleA(library)))
        
lib _LoadLibraryA(library); 
thread X frees library in between those calls, you ll end up w/ an invalid lib handle. GetModuleHandle does NOT increase ref count.
Reply With Quote
  #34  
Old 04-19-2018, 01:14
gigaman gigaman is offline
Friend
 
Join Date: Jun 2002
Posts: 80
Rept. Given: 0
Rept. Rcvd 3 Times in 2 Posts
Thanks Given: 0
Thanks Rcvd at 3 Times in 3 Posts
gigaman Reputation: 3
It could be changed to GetModuleHandleEx - but there's probably no point in not calling LoadLibrary directly?
Reply With Quote
  #35  
Old 04-19-2018, 07:08
bugficks bugficks is offline
Friend
 
Join Date: Apr 2018
Posts: 8
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 2
Thanks Rcvd at 6 Times in 2 Posts
bugficks Reputation: 0
if you simply replace it w/ GetModuleHandleEx or LoadLibrary you ll increase lib ref count every call.
Reply With Quote
  #36  
Old 04-19-2018, 16:34
mcp mcp is online now
Friend
 
Join Date: Dec 2011
Posts: 71
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 6
Thanks Rcvd at 17 Times in 9 Posts
mcp Reputation: 12
Which is what you want, unless performance is your top priority (likely isn't). You simply have to make sure to invoke FreeLibrary accordingly. That's why I subsequently proposed to make the actual call through a functor which would invoke FreeLibrary in the destructor.
Reply With Quote
  #37  
Old 04-19-2018, 18:05
bugficks bugficks is offline
Friend
 
Join Date: Apr 2018
Posts: 8
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 2
Thanks Rcvd at 6 Times in 2 Posts
bugficks Reputation: 0
youre mixing stuff up. that GetModuleHandle/LoadLibrary is from original post and thats C, functor in C w/ destructor?
my c++14 version keeps lib ref count constant, thats the sole purpose of the map (what you call 'cache')
also you want to keep lib loaded as dlls might have some init/deinit functions or keep some state between calls.

so if you want to fix version from original post use GetModuleHandleEx and call FreeLibrary later only if GetModuleHandleEx returned a valid handle.
for my c++ version just use thread_local on map like i ve already said before. this will also fix if a dll uses DLL_THREAD_ATTACH which a mutex does not.
Reply With Quote
  #38  
Old 04-19-2018, 19:03
mcp mcp is online now
Friend
 
Join Date: Dec 2011
Posts: 71
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 6
Thanks Rcvd at 17 Times in 9 Posts
mcp Reputation: 12
I was referring to the ref count problem: that can be trivially solved by having correct pairing of Load/FreeLibrary (and doing what i proposed earlier with a functor would do the right thing). I do not see how that is solved with the c++14 approach you posted? How are LoadLibrary / FreeLibrary calls matched without leaking library handles?

edit: ah got it, it's the shared pointer that points a custom deleter to FreeLibrary. ok. However, for all practical purposes this just keeps libraries loaded until the thread exits - which may or may not be what you want - you have no control over it.

edit2: to clarify, the functor approach was suggested because it inherently avoids unnecessary API lookups, e.g., if you invoke an API in a loop, you'll do the same lookup over and over again because you have coupled lookup with invocation of the API. The functor approach however decouples lookup from invoking, is thread-safe by definition and doesn't need any synchronization mechanisms.

Last edited by mcp; 04-19-2018 at 19:15.
Reply With Quote
  #39  
Old 04-19-2018, 20:40
bugficks bugficks is offline
Friend
 
Join Date: Apr 2018
Posts: 8
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 2
Thanks Rcvd at 6 Times in 2 Posts
bugficks Reputation: 0
w/ thread_local its a per thread map and lib is loaded/freed per thread, if that thread exits is see no problem there. OS lib ref count is the same as it was before thread was entered.

well again, this was just a c++ type safe replacement for original post, nothing more nothing less. if you want to do an uber lib loader youre free to do so

if you want to optimize lookup you could as well just add an optional opaque pointer and store some infos there.
e.g.:
PHP Code:
template <typename Ftypename... ArgTypes>
auto DynCallT(void **opaqueLPCTSTR libNameLPCSTR funcNameArgTypes... args)

    if(
opaque && *opaque
    { (
cast_opaque_t)(opaque) ...} 
    ... 
    if(
opaque
    { *
opaque=... }
    ...
}
void *ppp=0;
for(...) 
DynCallT(ppp, ...); 
anyways, it is what it is and it doesnt want to be more
Reply With Quote
  #40  
Old 05-08-2018, 05:08
aliali aliali is offline
Friend
 
Join Date: Jan 2002
Posts: 54
Rept. Given: 4
Rept. Rcvd 8 Times in 4 Posts
Thanks Given: 1
Thanks Rcvd at 5 Times in 4 Posts
aliali Reputation: 8
Quote:
Originally Posted by bugficks View Post
w/ thread_local its a per thread map and lib is loaded/freed per thread, if that thread exits is see no problem there. OS lib ref count is the same as it was before thread was entered.

well again, this was just a c++ type safe replacement for original post, nothing more nothing less. if you want to do an uber lib loader youre free to do so

if you want to optimize lookup you could as well just add an optional opaque pointer and store some infos there.
e.g.:
PHP Code:
template <typename Ftypename... ArgTypes>
auto DynCallT(void **opaqueLPCTSTR libNameLPCSTR funcNameArgTypes... args)

    if(
opaque && *opaque
    { (
cast_opaque_t)(opaque) ...} 
    ... 
    if(
opaque
    { *
opaque=... }
    ...
}
void *ppp=0;
for(...) 
DynCallT(ppp, ...); 
anyways, it is what it is and it doesnt want to be more
Is it possible to have a pure ANSI C implementation of the above code
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On



All times are GMT +8. The time now is 18:52.


ICP05004977
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX