I want to call a method periodically in a windows service built in C++. I am calling the method in SvcMain().
int main(int argc, char* argv[])
{
// The Services to run have to be added in this table.
// It takes the Service Name and the name of the method to be called by SC Manager.
// Add any additional services for the process to this table.
SERVICE_TABLE_ENTRY ServiceTable[]= {{SVCNAME,(LPSERVICE_MAIN_FUNCTION)SvcMain},{NULL,NULL}};
// This call returns when the service has stopped.
// The process should simply terminate when the call returns.
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
{
ConnectToServer();
}
Q1. Is this going to fire ConnectToServer() all the time or only once? I just don't know how win service works.
Q2.I want ConnectToServer() to be fired every 15 mins. How can I do that ?
EDIT: How can I create an installer for this service?
It's going to call SvcMain once. But you're not doing what you should in SvcMain. There's a good example on MSDN about Writing a ServiceMain function.
If you copy that example, you'd write your code to call ConnectToServer inside the SvcInit function (inside the while(1) loop). You can get the 15 minute delay between calls by specifying 15 minutes as the timeout value in the call to WaitForSingleObject.
If ConnectToServer is a long running process, you should probably find a way of breaking it up and introducing more calls to WaitForSingleObject within it, so that your service responds in a timely fashion to Stop requests.
Related
I have a C++ DLL created in VS2010. This DLL is responsible for generating a report and sending it to a server. This DLL is called by an another application which actually creates the data. Since sending the file to a server takes some time so, I don't want the calling application to wait till the DLL is busy in sending the file to a server.
To deal with the above-mentioned issue, I want to assign the task of sending file to a server (just one small function) to a separate thread and do not want to wait for this thread to complete (otherwise no benefit).
while(UserShutDownTheApp)
{
- Main App Gather Data
- Main App Call data management DLL and pass data to it
- DataManagementDLL: Generate a Report
- DataManagementDLL: Start a THREAD and Send report to Server by this THREAD. Do not wait for this THREAD to complete
- Main App finishes this iteration and is going to enter into next iteration.
}
Since, I do not have control on the main calling application, I can make modifications only inside the DLL. I am confused how should I implement this logic? I mean, what happens if the Thread has not completed the task of sending the file to the server and meanwhile the main calling application has already called this DLL the second time.
You should add a bit more logic to your DLL. First of all, the call to the DLL should not directly sends the data to the server, but queue the task (simply add all passed data to internal queue). The DLL can have internal worker thread which should be responsible for processing the queue of tasks.
How internal implementation and architecture should look like, depends on existing API (is it modifiable or not).
Hint - please take a look at DllMain() https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx - it should be helpful as an entry point.
it is not clear all your constraint but this is a simple example to use threads in c++:
void sendreport(std::string data)
{
std::cout << "send " << data;
std::this_thread::sleep_for(std::chrono::seconds(10));
}
std::queue<std::thread> jobs;
void addjob(std::string data)
{
while (jobs.size() > 10)
{
jobs.front().join();
jobs.pop();
}
jobs.emplace(sendreport, data);
}
void waitalljobs()
{
while (jobs.size() > 0)
{
jobs.front().join();
jobs.pop();
}
}
int main()
{
addjob("first");
addjob("second");
waitalljobs();
}
In this sample I use a queue and I limit the number of current thread to 10.
At the termination of the program waitalljobs wait for all thread had finished their works.
Referring to HTTP Server- Single threaded Implementation
I am trying to Explicitly control Lifetime of server instance
My Requirements are:
1) I should be able to explicitly destroy the server
2) I need to keep multiple Server Instances alive which should listen to different ports
3) Manager Class maintains list of all active server instances; should be able to create and destroy the server instances by create and drop methods
I am trying to implement Requirement 1 and
I have come up with code:
void server::stop()
{
DEBUG_MSG("Stopped");
io_service_.post(boost::bind(&server::handle_stop, this));
}
where handle_stop() is
void server::handle_stop()
{
// The server is stopped by cancelling all outstanding asynchronous
// operations. Once all operations have finished the io_service::run() call
// will exit.
acceptor_.close();
connection_manager_.stop_all();
}
I try to call it from main() as:
try
{
http::server::server s("127.0.0.1","8973");
// Run the server until stopped.
s.run();
boost::this_thread::sleep_for(boost::chrono::seconds(3));
s.stop();
}
catch (std::exception& e)
{
std::cerr << "exception: " << e.what() << "\n";
}
Question 1)
I am not able to call server::handle_stop().
I suppose io_service_.run() is blocking my s.stop() call.
void server::run()
{
// The io_service::run() call will block until all asynchronous operations
// have finished. While the server is running, there is always at least one
// asynchronous operation outstanding: the asynchronous accept call waiting
// for new incoming connections.
io_service_.run();
}
How do I proceed?
Question 2:
For requirement 2) where I need to have multiple server instances, i think I will need to create an io_service instance in main and must pass the same instance to all server instances. Am I right?
Is it mandatory to have only one io_service instance per process or can I have more than one ?
EDIT
My aim is to implement a class which can control multi server instances:
Something of below sort (Incorrect code // Just giving view, what I try to implement ) I want to achieve-
How do i design?
I have confusion regarding io_Service and how do I cleanly call mng.create(), mng.drop()
Class Manager{
public:
void createServer(ServerPtr)
{
list_.insert(make_shared<Server> (ip, port));
}
void drop()
{
list_.drop((ServerPtr));
}
private:
io_service iO_;
set<server> list_;
};
main()
{
io_service io;
Manager mng(io);
mng.createServer(ip1,port1);
mng.createServer(ip2,port2);
io.run();
mng.drop(ip1,port1);
}
I am not able to call server::handle_stop().
As you say, run() won't return until the service is stopped or runs out of work. There's no point calling stop() after that.
In a single-threaded program, you can call stop() from an I/O handler - for your example, you could use a deadline_timer to call it after three seconds. Or you could do something complicated with poll() rather than run(), but I wouldn't recommend that.
In a multi-threaded program, you could call it from another thread than the one calling run(), as long as you make sure it's thread-safe.
For [multiple servers] I think I will need to create an io_service instance in main
Yes, that's probably the best thing to do.
Is it mandatory to have only one io_service instance per process or can I have more than one?
You can have as many as you like. But I think you can only run one at a time on a single thread, so it would be tricky to have more than one in a single-threaded program. I'd have a single instance that all the servers can use.
You are right, it's not working because you call stop after blocking run, and run blocks until there are some unhandled callbacks. There are multiple ways to solve this and it depands from what part of program stop will be called:
If you can call it from another thread, then run each instance of server in separate thread.
If you need to stop server after some IO operation for example you can simply do as you have tried io_service_.post(boost::bind(&server::handle_stop, this));, but it should be registered from another thread or from another callback in current thread.
You can use io_service::poll(). It is non-blocking version of run, so you create a loop where you call poll until you need to stop server.
You can do it both ways. Even with the link you provided you can take a look at:
HTTP Server 3 - An HTTP server using a single io_service and a thread pool
and HTTP Server 2 - An HTTP server using an io_service-per-CPU design
I am using multi socket, however, I am confused with this API
int timer_callback(CURLM *multi, /* multi handle */
long timeout_ms, /* see above */
void *userp); /* private callback pointer *
CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_TIMERFUNCTION, timer_callback);
and I know that when the timeout changed, the callback function are called, however, the first time we register the callback function, for example:
curl_multi_setopt(handle, CURLMOPT_TIMERFUNCTION, timer_cb);
//and the callback function is
int timer_cb(CURLM *multi, long timeout_ms,void *userp)
{.....}
the second paramenter timeout_ms value is what? and I read the docs/example hiperfifo.c, and I see the log, this value is 1ms, how did this value come?
thanks
knuth
From the documentation:
CURLMOPT_TIMERFUNCTION - set callback to receive timeout values
int timer_callback(CURLM *multi, /* multi handle */<br>
long timeout_ms, /* see above *//<br
void *userp); /* private callback pointer */
This callback function will be called when the timeout value changes. The timeout_ms value is at what latest time the application should call one of the "performing" functions of the multi interface (curl_multi_socket_action and curl_multi_perform) - to allow libcurl to keep timeouts and retries etc to work. A timeout_ms value of -1 means that there is no timeout at all, and 0 means that the timeout is already expired. libcurl attempts to limit calling this only when the fixed future timeout time actually changes
Once a easy_handle is added to multi_handle via curl_multi_add_handle()[in this case, whenever a new_conn() is available], an internal 'jumpstart' is provided by creating a timeout action with 1ms as the timeout value.
Below comments from multi.c
/* Set the timeout for this multi handle to expire really soon so that it will be taken care of even when this multi handle is added in the midst of operation when only the curl_multi_socket() API is used. During that flow, only sockets that time-out or have actions will be dealt with. Since this handle has no action yet, we make sure it times out to get things to happen. */
Curl_expire(data, 1);
The actual timer callback set with CURLMOPT_TIMERFUNCTION is called inside update_timer() after Curl_expire()
Hope this helps.
I have an application built using MFC that I need to add Bonjour/Zeroconf service discovery to. I've had a bit of trouble figuring out how best to do it, but I've settled on using the DLL stub provided in the mDNSresponder source code and linking my application to the static lib generated by that (which in turn uses the system dnssd.dll).
However, I'm still having problems as the callbacks don't always seem to be being called so my device discovery stalls. What confuses me is that it all works absolutely fine under OSX, using the OSX dns-sd terminal service and under Windows using the dns-sd command line service. On that basis, I'm ruling out the client service as being the problem and trying to figure out what's wrong with my Windows code.
I'm basically calling DNSBrowseService(), then in that callback calling DNSServiceResolve(), then finally calling DNSServiceGetAddrInfo() to get the IP address of the device so I can connect to it.
All of these calls are based on using WSAAsyncSelect like this :
DNSServiceErrorType err = DNSServiceResolve(&client,kDNSServiceFlagsWakeOnResolve,
interfaceIndex,
serviceName,
regtype,
replyDomain,
ResolveInstance,
context);
if(err == 0)
{
err = WSAAsyncSelect((SOCKET) DNSServiceRefSockFD(client), p->m_hWnd, MESSAGE_HANDLE_MDNS_EVENT, FD_READ|FD_CLOSE);
}
But sometimes the callback just never gets called even though the service is there and using the command line will confirm that.
I'm totally stumped as to why this isn't 100% reliable, but it is if I use the same DLL from the command line. My only possible explanation is that the DNSServiceResolve function tries to call the callback function before the WSAAsyncSelect has registered the handling message for the socket, but I can't see any way around this.
I've spent ages on this and am now completely out of ideas. Any suggestions would be welcome, even if they're "that's a really dumb way to do it, why aren't you doing X, Y, Z".
I call DNSServiceBrowse, with a "shared connection" (see dns_sd.h for documentation) as in:
DNSServiceCreateConnection(&ServiceRef);
// Need to copy the main ref to another variable.
DNSServiceRef BrowseServiceRef = ServiceRef;
DNSServiceBrowse(&BrowseServiceRef, // Receives reference to Bonjour browser object.
kDNSServiceFlagsShareConnection, // Indicate it's a shared connection.
kDNSServiceInterfaceIndexAny, // Browse on all network interfaces.
"_servicename._tcp", // Browse for service types.
NULL, // Browse on the default domain (e.g. local.).
BrowserCallBack, // Callback function when Bonjour events occur.
this); // Callback context.
This is inside a main run method of a thread class called ServiceDiscovery. ServiceRef is a member of ServiceDiscovery.
Then immediately following the above code, I have a main event loop like the following:
while (true)
{
err = DNSServiceProcessResult(ServiceRef);
if (err != kDNSServiceErr_NoError)
{
DNSServiceRefDeallocate(BrowseServiceRef);
DNSServiceRefDeallocate(ServiceRef);
ServiceRef = nullptr;
}
}
Then, in BrowserCallback you have to setup the resolve request:
void DNSSD_API ServiceDiscovery::BrowserCallBack(DNSServiceRef inServiceRef,
DNSServiceFlags inFlags,
uint32_t inIFI,
DNSServiceErrorType inError,
const char* inName,
const char* inType,
const char* inDomain,
void* inContext)
{
(void) inServiceRef; // Unused
ServiceDiscovery* sd = (ServiceDiscovery*)inContext;
...
// Pass a copy of the main DNSServiceRef (just a pointer). We don't
// hang to the local copy since it's passed in the resolve callback,
// where we deallocate it.
DNSServiceRef resolveServiceRef = sd->ServiceRef;
DNSServiceErrorType err =
DNSServiceResolve(&resolveServiceRef,
kDNSServiceFlagsShareConnection, // Indicate it's a shared connection.
inIFI,
inName,
inType,
inDomain,
ResolveCallBack,
sd);
Then in ResolveCallback you should have everything you need.
// Callback for Bonjour resolve events.
void DNSSD_API ServiceDiscovery::ResolveCallBack(DNSServiceRef inServiceRef,
DNSServiceFlags inFlags,
uint32_t inIFI,
DNSServiceErrorType inError,
const char* fullname,
const char* hosttarget,
uint16_t port, /* In network byte order */
uint16_t txtLen,
const unsigned char* txtRecord,
void* inContext)
{
ServiceDiscovery* sd = (ServiceDiscovery*)inContext;
assert(sd);
// Save off the connection info, get TXT records, etc.
...
// Deallocate the DNSServiceRef.
DNSServiceRefDeallocate(inServiceRef);
}
hosttarget and port contain your connection info, and any text records can be obtained using the DNS-SD API (e.g. TXTRecordGetCount and TXTRecordGetItemAtIndex).
With the shared connection references, you have to deallocate each one based on (or copied from) the parent reference when you are done with them. I think the DNS-SD API does some reference counting (and parent/child relationship) when you pass copies of a shared reference to one of their functions. Again, see the documentation for details.
I tried not using shared connections at first, and I was just passing down ServiceRef, causing it to be overwritten in the callbacks and my main loop to get confused. I imagine if you don't use shared connections, you need to maintain a list of references that need further processing (and process each one), then destroy them when you're done. The shared connection approach seemed much easier.
I've been having some issues getting my method hooks to work. I can get the hook to work if "I" call the method that's being hooked. But when it occurs naturally during the processes operation, it doesn't get hooked. My problem is probably stemming from the fact that I'm actually setting these hooks in my own thread that I've spawned. And apparently the LhSetInclusiveACL() method needs to know the thread that you want to hook. Well, here are my issues...
I don't really care which threads apply the hook, i want them all to be hooked. For example, lets say I want the CreateICW() method from the "gdi32.dll" library hooked for the entire process "iexplorer.exe". Not just from thread ID number 48291 or whatever. Knowing which threads are going to be calling the routines you are interested in hooking requires intimate knowledge of internal workings of the process you are hooking. I'm speculating that is generally not feasible and certainly not feasible for me. Thus its kind of impossible for me to know a priori which thread IDs need to be hooked.
The following code was taken from the "UnmanageHook" example:
extern "C" int main(int argc, wchar_t* argv[])
{
//...
//...
//...
/*
The following shows how to install and remove local hooks...
*/
FORCE(LhInstallHook(
GetProcAddress(hUser32, "MessageBeep"),
MessageBeepHook,
(PVOID)0x12345678,
hHook));
// won't invoke the hook handler because hooks are inactive after installation
MessageBeep(123);
// activate the hook for the current thread
// This is where I believe my problem is. ACLEntries is
// supposed to have a list of thread IDs that should pay
// attention to the MessageBeep() hook. Entries that are
// "0" get translated to be the "current" threadID. I want
// ALL threads and I don't want to have to try to figure out
// which threads will be spawned in the future for the given
// process. The second parameter is InThreadCount. I'm
// kind of shocked that you can't just pass in 0 or -1 or
// something for this parameter and just have it hook all
// threads in that given process.
FORCE(LhSetInclusiveACL(ACLEntries, 1, hHook));
// will be redirected into the handler...
MessageBeep(123);
//...
//...
//...
}
I've added some comments to the LhSetInclusiveACL() method call explaining the situation. Also LhSetExclusiveACL() and the "global" versions for these methods don't seem to help either.
For reference here is the documentation for LhSetExclusiveACL:
/***********************************************************************
Sets an exclusive hook local ACL based on the given thread ID list.
Global and local ACLs are always intersected. For example if the
global ACL allows a set “G” of threads to be intercepted, and the
local ACL allows a set “L” of threads to be intercepted, then the
set “G L” will be intercepted. The “exclusive” and “inclusive”
ACL types don’t have any impact on the computation of the final
set. Those are just helpers for you to construct a set of threads.
EASYHOOK_NT_EXPORT LhSetExclusiveACL(
ULONG* InThreadIdList,
ULONG InThreadCount,
TRACED_HOOK_HANDLE InHandle);
Parameters:
InThreadIdList
An array of thread IDs. If you specific zero for an
entry in this array, it will be automatically replaced
with the calling thread ID.
InThreadCount
The count of entries listed in the thread ID list. This
value must not exceed MAX_ACE_COUNT!
InHandle
The hook handle whose local ACL is going to be set.
Return values:
STATUS_INVALID_PARAMETER_2
The limit of MAX_ACE_COUNT ACL is violated by the given buffer.
***********************************************************************/
Am I using this wrong? I imagine that this is how the majority of implementations would use this library, so why is this not working for me?
You want to use LhSetExclusiveACL instead. This means that any calls across any threads get hooked, except for ones you specify in the ACL.