Exetools  

Go Back   Exetools > 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: 3
Thanks Rcvd at 14 Times in 8 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
The Following User Says Thank You to bugficks For This Useful Post:
Indigo (07-19-2019)
  #32  
Old 04-15-2018, 18:48
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 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
The Following User Says Thank You to mcp For This Useful Post:
Indigo (07-19-2019)
  #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: 3
Thanks Rcvd at 14 Times in 8 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
The Following User Says Thank You to bugficks For This Useful Post:
Indigo (07-19-2019)
  #34  
Old 04-19-2018, 01:14
gigaman gigaman is offline
Friend
 
Join Date: Jun 2002
Posts: 87
Rept. Given: 0
Rept. Rcvd 3 Times in 2 Posts
Thanks Given: 0
Thanks Rcvd at 14 Times in 11 Posts
gigaman Reputation: 4
It could be changed to GetModuleHandleEx - but there's probably no point in not calling LoadLibrary directly?
Reply With Quote
The Following User Says Thank You to gigaman For This Useful Post:
Indigo (07-19-2019)
  #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: 3
Thanks Rcvd at 14 Times in 8 Posts
bugficks Reputation: 0
if you simply replace it w/ GetModuleHandleEx or LoadLibrary you ll increase lib ref count every call.
Reply With Quote
The Following User Says Thank You to bugficks For This Useful Post:
Indigo (07-19-2019)
  #36  
Old 04-19-2018, 16:34
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 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
The Following User Says Thank You to mcp For This Useful Post:
Indigo (07-19-2019)
  #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: 3
Thanks Rcvd at 14 Times in 8 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
The Following User Says Thank You to bugficks For This Useful Post:
Indigo (07-19-2019)
  #38  
Old 04-19-2018, 19:03
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 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
The Following User Says Thank You to mcp For This Useful Post:
Indigo (07-19-2019)
  #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: 3
Thanks Rcvd at 14 Times in 8 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
The Following User Says Thank You to bugficks For This Useful Post:
Indigo (07-19-2019)
  #40  
Old 05-08-2018, 05:08
aliali aliali is offline
Friend
 
Join Date: Jan 2002
Posts: 59
Rept. Given: 4
Rept. Rcvd 8 Times in 4 Posts
Thanks Given: 1
Thanks Rcvd at 13 Times in 8 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
The Following User Says Thank You to aliali For This Useful Post:
Indigo (07-19-2019)
  #41  
Old 10-17-2018, 19:36
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
Quote:
Originally Posted by aliali View Post
Is it possible to have a pure ANSI C implementation of the above code
not possible, as i know, but there can be work around at lower levels
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Calling any function dynamically without typedef Succubus Source Code 0 10-21-2021 16:34
[MASM Source] - ZwCreateThread example (winAPI CreateThread emulation) TomaHawk Source Code 4 09-08-2019 14:06
WinAPI: No WM_COMMAND Message? aldente General Discussion 2 07-05-2006 07:17


All times are GMT +8. The time now is 16:51.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )