I've tried my best to convert an injected Dll from C++ to D and came to that point where I want to unload the Dll dynamically, when F7 gets pressed.
In C++ it was simple to use FreeLibraryAndExitThread to let the Dll unload itself, but the method doesn't seem to work when used in the D Dll.
Here you can see the working C++ code:
// Module.cpp
void Module::QuitThread()
{
while (true) {
// KeyPress
if ((GetAsyncKeyState(VK_F7) & 0x8000) != 0) {
break;
}
Sleep(1);
}
FreeLibraryAndExitThread(Module::_hDllModule, 0);
}
I know this is the quick and dirty way, but it's enough for now. Here is the D equivalent:
// module.d
private void quitThread()
{
while (true) {
// KeyPress
if (GetAsyncKeyState(VK_F7) & 0x8000) {
break;
}
Sleep(1);
}
FreeLibraryAndExitThread(_hModule, 0);
}
Is this the expected behavior? How am I supposed to unload the D Dll?
Related
Background:
Application Type: Win32 Application
Language: C++ (with C functions as well)
Problem: Want to use main Window Handle in another file.
Update 1: Using a TCP server in another thread. This server receives information from a client and then needs to start a timer in the program.
Project Layout:
Main File: main.cpp/main.h which has WinMain, WndProc, etc.
Other Generated Files: Resource.h, main.rc, stdafx.h etc generated by Visual Studio
Self Made Files: functions.cpp/functions.h & calculation.cpp/calculation.h
Update 1: Server thread is in the main.cpp file and the call to start the timer is made on the server thread. I also updated some of the code to more accurately reflect what I have.
Info:
Can I call SetTimer(hwnd, TIMER_INT, TIMER_INTERVAL, NULL) in the calculation.cpp file in some way and make the TIMER_INT timer trigger in the WndProc for WM_TIMER?
So for example (of course foo is defined in calculation.h, etc. for other functions).
//calculation.cpp
void foo(HWND hwnd)
{
SetTimer(hwnd, TIMER_INT, TIMER_INTERVAL, NULL);
}
//functions.cpp
void ThreadStart()
{
/* This code initializes a working server that is visible to main.cpp */
/* The Server socket and Accept socket are extern for main.cpp */
}
//main.cpp
HWND hwnd;
int WinMain(...)
{
//... Set hwnd here
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, ...)
{
static PARAMS params; //Thread params
switch(message)
{
case WM_CREATE:
//This initializes a blocking Server (which works)
params.hwnd = hWnd;
params.bContinue = TRUE;
_beginthread(ThreadServer, 0, ¶ms);
break;
case WM_TIMER:
case TIMER_INT:
MessageBox(NULL, L"Timer was triggered from foo", L"FOO", NULL);
//continuous messageboxes will appear based on TIMER_INTERVAL if it works...
break;
break;
}
}
void ThreadServer(PVOID pvoid)
{
ThreadStart(); //calls accept() until client connects
while(1)
{
memset(&RecvBuffer[0], 0, 512 * sizeof(RecvBuffer[0])); //Clear recv
TCPServer.iRecv = recv(AcceptSocket, RecvBuffer, iRecvBuffer, 0);
if(strlen(RecvBuffer) > 1){
memset(&SendBuffer[0], 0, 512 * sizeof(SendBuffer[0]));
//Clears SendBuffer
std::string retString = "";
retString = process(RecvBuffer); //processes RecvBuffer
if(condition == true){
foo(hwnd);
}
if(strlen(retString.c_str()) > 0){
TCPServer.iSend = send(AcceptSocket, retString.c_str(), strlen(retString.c_str()), 0);
}else{
retString = "";
TCPServer.iSend = send(AcceptSocket, retString.c_str(), strlen(retString.c_str()), 0);
}
if(TCPServer.iSend == SOCKET_ERROR){
break;
}
}
//Determine if socket fails and breaks if failure occurs
//*
memset(&SendBuffer[0], 0, 512 * sizeof(SendBuffer[0]));
TCPServer.iSend = send(AcceptSocket, SendBuffer, iSendBuffer, 0);
if(TCPServer.iSend == SOCKET_ERROR){
break;
}//*/
Sleep(1);
}
}
The issue is trying to pass a reference to hwnd to calculation.cpp from the server thread. I can pass hwnd to the function foo(HWND), but the timer does not set. Is there a way to set a timer in a separate thread or is this not possible? Is there any other workaround to this with using winsock and a server?
As the document state that you can't create a timer for a window from a different thread. For you the different thread is the server thread.
Maybe you can post WM_TIMER message (PostMessage) to the main thread from the server thread when the timer timeout.
Or you need Synchronization Objects for threads synchronicity.
I have a MFC Application that sometime work on touch screen
I want to open my virtual keyboard when focused edit box if keyboard isn't attached
Here's a quick attempt at using GetRawInputDeviceList to check for presence of a RIM_TYPEKEYBOARD device. I've skimped on the error handling though but hopefully it's obvious where it needs it. This does detect me removing my USB keyboard.
bool detectKeyboard() {
bool bHasKeyboard = false;
UINT nDevices;
UINT ret = GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));
if (ret == 0) {
PRAWINPUTDEVICELIST pRawInputDeviceList = new RAWINPUTDEVICELIST[nDevices];
ret = GetRawInputDeviceList(pRawInputDeviceList, &nDevices,
sizeof(RAWINPUTDEVICELIST));
if (ret != (UINT)-1) {
for (UINT i = 0; i < nDevices; ++i) {
if (pRawInputDeviceList[i].dwType == RIM_TYPEKEYBOARD) {
bHasKeyboard = true;
break;
}
}
}
// else error calling GetRawInputDeviceList to fetch the devices list
delete[] pRawInputDeviceList;
}
// else error calling GetRawInputDeviceList to return number of devices
return bHasKeyboard;
}
(And it's been a while since I wrote C++ or MFC so apologies for any poor style.)
I'm implementing flow control in a custom protocol in the linux kernel. When I receive an ACK, I want to remove the acked packets from the write queue. Here's some code
for(i = (ack->sequence - qp->first_unack); i>0&&sk->sk_write_queue.qlen>0; i++){
skb_del = skb_dequeue(&sk->sk_write_queue);
qp->first_unack++;
kfree_skb(skb_del);
}
I get a kernel freeze from this code. Everything works well however, when I comment out the kfree(skb_del). Any ideas why is this happening? How else can I free up the memory?
As the skbs are queued to the socket you can use already provided socket APIs;
sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_early) // copied_ealy = 0
For more details you can track tcp_recvmsg, there properly you will get the impementation flow
Moreove why you are using custom APIS from the queuing/dequeuing loop on your own. Just go through the include/net/sock.h I hope you will get necessary details
This is probably because of double freeing skb_del.
Theoretically, before calling kfree_skb(skb_del) you can check the value of skb_del->users by doing refcount_read(&skb_del->users), and if skb_del->users is 0, then it means that skb_del has already been freed.
In practice, the kfree_skb() function doesn't set skb_del->users to 0 when skb_del is finally released (due to some optimization considerations), so after skb_del will be release it would stay 1, and you won't be able to know if skb_del has been released or not.
If you are still curious if this is a double-free issue and you are fine with making some changes in the skbuff infrastructure (just for this investigation) then we need to modify some skbuff functions.
WARNING: It's very easy to cause the kernel to crash when playing with this function, so be careful. But these modification works (in this way I've found a double-free of skb). Keep in mind that this is a suggestion only for investigating the double-free issue, and I've no idea if these modifications will effect your system in the long-run.
We'll modify the following functions (based on kernel v5.9.1):
skb_unref() // from include/linux/skbuff.h
__kfree_skb() // from net/core/skbuff.c
kfree_skb() // from net/core/skbuff.c
consume_skb() // from net/core/skbuff.c
Original skb_unref()
static inline bool skb_unref(struct sk_buff *skb)
{
if (unlikely(!skb))
return false;
if (likely(refcount_read(&skb->users) == 1))
smp_rmb();
else if (likely(!refcount_dec_and_test(&skb->users)))
return false;
return true;
}
Modified skb_unref()
static inline bool skb_unref(struct sk_buff *skb)
{
if (unlikely(!skb))
return false;
if (likely(refcount_read(&skb->users) == 1)) {
smp_rmb();
refcount_set(&skb->users, 0);
} else if (likely(!refcount_dec_and_test(&skb->users))) {
return false;
}
return true;
}
Original __kfree_skb()
void __kfree_skb(struct sk_buff *skb)
{
skb_release_all(skb);
kfree_skbmem(skb);
}
Modified __kfree_skb()
void __kfree_skb(struct sk_buff *skb)
{
if (!skb_unref(skb))
return;
skb_release_all(skb);
kfree_skbmem(skb);
}
Original kfree_skb()
void kfree_skb(struct sk_buff *skb)
{
if (!skb_unref(skb))
return;
trace_kfree_skb(skb, __builtin_return_address(0));
__kfree_skb(skb);
}
Modified kfree_skb()
void kfree_skb(struct sk_buff *skb)
{
//if (!skb_unref(skb))
// return;
trace_kfree_skb(skb, __builtin_return_address(0));
__kfree_skb(skb);
}
Original consume_skb()
void consume_skb(struct sk_buff *skb)
{
if (!skb_unref(skb))
return;
trace_consume_skb(skb);
__kfree_skb(skb);
}
Modified consume_skb()
void consume_skb(struct sk_buff *skb)
{
//if (!skb_unref(skb))
// return;
trace_consume_skb(skb);
__kfree_skb(skb);
}
Good luck in the investigation.
May god will be with you.
I'm totally new to c++ Gui..
i'm trying to make a simple windows form to draw on my dining philosophers semaphore solution
my semaphore header file
ref class sema4
{
private:
int sem_value;
queue Waiting_List;
public:
sema4();
void wait(HANDLE h);
void signal();
};
My semaphore cpp
sema4::sema4()
{
sem_value=1;
}
//suspend the thread
void sema4::wait(HANDLE h)
{
sem_value = sem_value - 1;
if (sem_value < 0)
{
Waiting_List.enqueue(h);
SuspendThread(h);
}
}
//Resume the thread
void sema4::signal()
{
sem_value = sem_value + 1;
if (sem_value <= 0)
{
ResumeThread(Waiting_List.dequeue());
}
}
My queue header file
ref class queue
{
private:
HANDLE list[20];
int front;
int rear;
public:
queue();
void enqueue(HANDLE x);
HANDLE dequeue();
bool isempty();
bool isfull();
};
the queue CPP
queue::queue()
{
front=-1;
rear=-1;
}
void queue::enqueue(HANDLE x)
{
if(isfull())
{
cout<<"queue is full";
}
else
{
if(front==-1)
front=0;
rear=(rear+1)%20;
list[rear]=x;
}
}
bool queue::isfull(){
if (front==(rear+1)%20)
return true;
return false;
}
HANDLE queue::dequeue(){
if(isempty())
{
cout<<"queue is empty";
return NULL;
}
else
{
HANDLE x =alist[front];
if (front==rear)
front=rear=-1;
else front = (front + 1) % 20;
}
}
bool queue::isempty()
{
if((front == rear) && (rear == -1))
{
return true;
}
return false;
}
i keep getting the error C4368: cannot define 'list' as a member of managed 'queue': mixed types are not supported
and i have no real experience using c++ windows forms
The simple answer
The compile error you're getting is because queue is a managed type. Managed types need to be declared with a ^, and created using gcnew.
The more complex answer
What you're writing isn't C++ code. This is a language called C++/CLI, which is intended for interop between .Net managed languages such as C# and unmanaged languages such as C and C++. As such, it has all of the complexities of C++, all of the complexities of C#, and a few extra of its own.
While you're just learning, please pick one or the other, and go with that. If you want to write managed code, learn C#. If you want to write unmanaged code, learn C++. Don't tackle C++/CLI while you're still learning.
Question
What can I do to get a locking mechanism that provides minimal and stable latency while guaranteeing that a thread cannot reacquire a resource before another thread has acquired and released it?
The desirability of answers to this question are ranked as follows:
Some combination of built-in C++11 features that work in MinGW on Windows 7 (note that the <thread> and <mutex> libraries do not work on a Windows platform)
Some combination of Windows API features
A modification to the FairLock listed below, my own attempt at implementing such a mechanism
Some features provided by a free, open-source library that does not require a .configure/make/make install process, (getting that to work in MSYS is more of an adventure than I care for)
Background
I am writing an application which is effectively a multi-stage producer/consumer. One thread generates input consumed by another thread, which produces output consumed by yet another thread. The application uses pairs of buffers so that, after an initial delay, all threads can work nearly simultaneously.
Since I am writing a Windows 7 application, I had been using CriticalSections to guard the buffers. The problem with using CriticalSections (or, so far as I can tell, any other Windows or C++11-built-in synchronization object) is that it does not allow for any provision that a thread that just released a lock cannot reacquire it until another thread has done so first. Because of this, many of my test drivers for the middle thread (the Encoder) never gave the Encoder a chance to acquire the test input buffers and completed without having tested them. The end result was a ridiculous process of trying to determine an artificial wait time that stochastically worked for my machine.
Since the structure of my application requires that each stage waits for the other stage to have acquired, finished using, and released the necessary buffers for getting to use the buffer again, I need, for lack of a better term, a fair locking mechanism. I took a crack at writing one (the source code is provided below). In testing, this FairLock allows my test driver to run my Encoder at the same speeds that I was able to achieve using the CriticalSection maybe 60% of the runs. The other 40% of the runs take anywhere between 10 to 100 ms longer, which is not acceptable for my application.
FairLock
// FairLock.hpp
#ifndef FAIRLOCK_HPP
#define FAIRLOCK_HPP
#include <atomic>
using namespace std;
class FairLock {
private:
atomic_bool owned {false};
atomic<DWORD> lastOwner {0};
public:
FairLock(bool owned);
bool inline hasLock() const;
bool tryLock();
void seizeLock();
void tryRelease();
void waitForLock();
};
#endif
// FairLock.cpp
#include <windows.h>
#include "FairLock.hpp"
#define ID GetCurrentThreadId()
FairLock::FairLock(bool owned) {
if (owned) {
this->owned = true;
this->lastOwner = ID;
} else {
this->owned = false;
this->lastOwner = 0;
}
}
bool inline FairLock::hasLock() const {
return owned && lastOwner == ID;
}
bool FairLock::tryLock() {
bool success = false;
DWORD id = ID;
if (owned) {
success = lastOwner == id;
} else if (
lastOwner != id &&
owned.compare_exchange_strong(success, true)
) {
lastOwner = id;
success = true;
} else {
success = false;
}
return success;
}
void FairLock::seizeLock() {
bool success = false;
DWORD id = ID;
if (!(owned && lastOwner == id)) {
while (!owned.compare_exchange_strong(success, true)) {
success = false;
}
lastOwner = id;
}
}
void FairLock::tryRelease() {
if (hasLock()) {
owned = false;
}
}
void FairLock::waitForLock() {
bool success = false;
DWORD id = ID;
if (!(owned && lastOwner == id)) {
while (lastOwner == id); // spin
while (!owned.compare_exchange_strong(success, true)) {
success = false;
}
lastOwner = id;
}
}
EDIT
DO NOT USE THIS FairLock CLASS; IT DOES NOT GUARANTEE MUTUAL EXCLUSION!
I reviewed the above code to compare it against The C++ Programming Language: 4th Edition text I had not read carefully and what CouchDeveloper's recommended Synchronous Queue. I realized that there are several sequences in which the thread that just released the FairLock can be tricked into thinking it still owns it. All it takes is interleaving instructions as follows:
New owner: set owned to true
Old owner: is owned true? yes
Old owner: am I the last owner? yes
New owner: set me as the last owner
At this point, the old and new owners both enter their critical sections.
I am considering whether this problem has a solution and whether it is worth attempting to solve this at all. In the meantime, don't use this unless you see a fix.
I would implement this in C++11 using a condition_variable-per-thread setup so that I could choose exactly which thread to wake up when (Live demo at Coliru):
class FairMutex {
private:
class waitnode {
std::condition_variable cv_;
waitnode* next_ = nullptr;
FairMutex& fmtx_;
public:
waitnode(FairMutex& fmtx) : fmtx_(fmtx) {
*fmtx.tail_ = this;
fmtx.tail_ = &next_;
}
~waitnode() {
for (waitnode** p = &fmtx_.waiters_; *p; p = &(*p)->next_) {
if (*p == this) {
*p = next_;
if (!next_) {
fmtx_.tail_ = &fmtx_.waiters_;
}
break;
}
}
}
void wait(std::unique_lock<std::mutex>& lk) {
while (fmtx_.held_ || fmtx_.waiters_ != this) {
cv_.wait(lk);
}
}
void notify() {
cv_.notify_one();
}
};
waitnode* waiters_ = nullptr;
waitnode** tail_ = &waiters_;
std::mutex mtx_;
bool held_ = false;
public:
void lock() {
auto lk = std::unique_lock<std::mutex>{mtx_};
if (held_ || waiters_) {
waitnode{*this}.wait(lk);
}
held_ = true;
}
bool try_lock() {
if (mtx_.try_lock()) {
std::lock_guard<std::mutex> lk(mtx_, std::adopt_lock);
if (!held_ && !waiters_) {
held_ = true;
return true;
}
}
return false;
}
void unlock() {
std::lock_guard<std::mutex> lk(mtx_);
held_ = false;
if (waiters_ != nullptr) {
waiters_->notify();
}
}
};
FairMutex models the Lockable concept so it can be used like any other standard library mutex type. Put simply, it achieves fairness by inserting waiters into a list in arrival order, and passing the mutex to the first waiter in the list when unlocking.
If it's useful:
This demonstrates *) an implementation of a "synchronous queue" using semaphores as synchronization primitives.
Note: the actually implementation uses semaphores implemented with GCD (Grand Central Dispatch):
using gcd::mutex;
using gcd::semaphore;
// A blocking queue in which each put must wait for a get, and vice
// versa. A synchronous queue does not have any internal capacity,
// not even a capacity of one.
template <typename T>
class simple_synchronous_queue {
public:
typedef T value_type;
enum result_type {
OK = 0,
TIMEOUT_NOT_DELIVERED = -1,
TIMEOUT_NOT_PICKED = -2,
TIMEOUT_NOTHING_OFFERED = -3
};
simple_synchronous_queue()
: sync_(0), send_(1), recv_(0)
{
}
void put(const T& v) {
send_.wait();
new (address()) T(v);
recv_.signal();
sync_.wait();
}
result_type put(const T& v, double timeout) {
if (send_.wait(timeout)) {
new (storage_) T(v);
recv_.signal();
if (sync_.wait(timeout)) {
return OK;
}
else {
return TIMEOUT_NOT_PICKED;
}
}
else {
return TIMEOUT_NOT_DELIVERED;
}
}
T get() {
recv_.wait();
T result = *address();
address()->~T();
sync_.signal();
send_.signal();
return result;
}
std::pair<result_type, T> get(double timeout) {
if (recv_.wait(timeout)) {
std::pair<result_type, T> result =
std::pair<result_type, T>(OK, *address());
address()->~T();
sync_.signal();
send_.signal();
return result;
}
else {
return std::pair<result_type, T>(TIMEOUT_NOTHING_OFFERED, T());
}
}
private:
using storage_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
T* address() {
return static_cast<T*>(static_cast<void*>(&storage_));
}
storage_t storage_;
semaphore sync_;
semaphore send_;
semaphore recv_;
};
*) demonstrates: be carefully about potential issues, could be improved, etc. ... ;)
I accepted CouchDeveloper's answer since it pointed me down the right path. I wrote a Windows-specific C++11 implementation of a synchronous queue, and added this answer so that others could consider/use it if they so choose.
// SynchronousQueue.hpp
#ifndef SYNCHRONOUSQUEUE_HPP
#define SYNCHRONOUSQUEUE_HPP
#include <atomic>
#include <exception>
#include <windows>
using namespace std;
class CouldNotEnterException: public exception {};
class NoPairedCallException: public exception {};
template typename<T>
class SynchronousQueue {
private:
atomic_bool valueReady {false};
CRITICAL_SECTION getCriticalSection;
CRITICAL_SECTION putCriticalSection;
DWORD wait {0};
HANDLE getSemaphore;
HANDLE putSemaphore;
const T* address {nullptr};
public:
SynchronousQueue(DWORD waitMS): wait {waitMS}, address {nullptr} {
initializeCriticalSection(&getCriticalSection);
initializeCriticalSection(&putCriticalSection);
getSemaphore = CreateSemaphore(nullptr, 0, 1, nullptr);
putSemaphore = CreateSemaphore(nullptr, 0, 1, nullptr);
}
~SynchronousQueue() {
EnterCriticalSection(&getCriticalSection);
EnterCriticalSection(&putCriticalSection);
CloseHandle(getSemaphore);
CloseHandle(putSemaphore);
DeleteCriticalSection(&putCriticalSection);
DeleteCriticalSection(&getCriticalSection);
}
void put(const T& value) {
if (!TryEnterCriticalSection(&putCriticalSection)) {
throw CouldNotEnterException();
}
ReleaseSemaphore(putSemaphore, (LONG) 1, nullptr);
if (WaitForSingleObject(getSemaphore, wait) != WAIT_OBJECT_0) {
if (WaitForSingleObject(putSemaphore, 0) == WAIT_OBJECT_0) {
LeaveCriticalSection(&putCriticalSection);
throw NoPairedCallException();
} else {
WaitForSingleObject(getSemaphore, 0);
}
}
address = &value;
valueReady = true;
while (valueReady);
LeaveCriticalSection(&putCriticalSection);
}
T get() {
if (!TryEnterCriticalSection(&getCriticalSection)) {
throw CouldNotEnterException();
}
ReleaseSemaphore(getSemaphore, (LONG) 1, nullptr);
if (WaitForSingleObject(putSemaphore, wait) != WAIT_OBJECT_0) {
if (WaitForSingleObject(getSemaphore, 0) == WAIT_OBJECT_0) {
LeaveCriticalSection(&getCriticalSection);
throw NoPairedCallException();
} else {
WaitForSingleObject(putSemaphore, 0);
}
}
while (!valueReady);
T toReturn = *address;
valueReady = false;
LeaveCriticalSection(&getCriticalSection);
return toReturn;
}
};
#endif