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.
Related
So, I've advertised for DCCA application in my extension via fd_disp_register and I can parse and prepare the response message and at the end sending them from my callback function with no issue.
This always works if the answer message is prepared inside of callback function. But what if i want to reply the request message outside of my callback function ?
So, I tried it with a sample code. I changed the callback function logic so there were no sending message from it and instead another thread tries to fetch some information and send out the response.
This absolutely failed, because as soon as callback returns (with 0), the next action gonna take place (according to disp_action value) which is not in my favor.
So, I'd like to ask what is your solution to handle such case, I mean sending out the response messages outside of the callback function ?
Thanks.
I'm not sure I've ever done this before, but looking at libfdproto.h...
enum disp_action {
DISP_ACT_CONT, /* The next handler should be called, unless *msg == NULL. */
DISP_ACT_SEND, /* The updated message must be sent. No further callback is called. */
DISP_ACT_ERROR /* An error must be created and sent as a reply -- not valid for callbacks, only for fd_msg_dispatch. */
};
...it sounds like you want to set *act = DISP_ACT_CONT; and *msg = NULL; (because you've taken ownership of the message).
Does that work?
Is there a way to check for data for a certain time in asio?
I have a client with an asio socket which has a Method
bool ASIOClient::hasData()
{
return m_socket->available();
}
And i'd like to have some kind of delay here so it checks for data for like 1 second max and returns more ealy. Moreover i don't want to poll it for obvious reason that it meight take a second. The reaseon why i use this is, that i do send data to a client and wait for the respond. If he doesnt respond in a certain time i'd close the socket. Thats what the hasData is mentioned for.
I know that it is nativ possible with an select and an fd_set.
The asio Client is created in an Accept method of the server socket class and later used to handle requests and send back data to the one who connected here.
int ASIOServer::accept(const bool& blocking)
{
auto l_sock = std::make_shared<asio::ip::tcp::socket>(m_io_service);
m_acceptor.accept(*l_sock);
auto l_client = std::make_shared<ASIOClient>(l_sock);
return 0;
}
You just need to attempt to read.
The usual approach is to define deadlines for all asynchronous operations that could take "long" (or even indefinitely long).
This is quite natural in asynchronous executions:
Just add a deadline timer:
boost::asio::deadline_timer tim(svc);
tim.expires_from_now(boost::posix_time::seconds(2));
tim.async_wait([](error_code ec) {
if (!ec) // timer was not canceled, so it expired
{
socket_.cancel(); // cancel pending async operation
}
});
If you want to use it with synchronous calls, you can with judicious use of poll() instead of run(). See this answer: boost::asio + std::future - Access violation after closing socket which implements a helper await_operation that runs a single operations synchronously but under a timeout.
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.
i'm studying this source base. Basically this is an Anim server client for Symbian 3rd edition for the purpose of grabbing input events without consuming them in a reliable way.
If you spot this line of the server, here it is basically setting the RProperty value (apparently to an increasing counter); it seems no actual processing of the input is done.
inside this client line, the client is supposed to be receiving the notification data, but it only calls Attach.
my understanding is that Attach is only required to be called once, but is not clear in the client what event is triggered every time the server sets the RProperty
How (and where) is the client supposed to access the RProperty value?
After Attaching the client will somewhere Subscribe to the property where it passes a TRequestStatus reference. The server will signal the request status property via the kernel when the asynchronous event has happened (in your case the property was changed). If your example source code is implemented in the right way, you will find an active object (AO; CActive derived class) hanging around and the iStatus of this AO will be passed to the RProperty API. In this case the RunL function of the AO will be called when the property has been changed.
It is essential in Symbian to understand the active object framework and quite few people do it actually. Unfortunately I did not find a really good description online (they are explained quite well in Symbian OS Internals book) but this page at least gives you a quick example.
Example
In the ConstructL of your CMyActive subclass of CActive:
CKeyEventsClient* iClient;
RProperty iProperty;
// ...
void CMyActive::ConstructL()
{
RProcess myProcess;
TSecureId propertyCategory = myProcess.SecureId();
// avoid interference with other properties by defining the category
// as a secure ID of your process (perhaps it's the only allowed value)
TUint propertyKey = 1; // whatever you want
iClient = CKeyEventsClient::NewL(propertyCategory, propertyKey, ...);
iClient->OpenNotificationPropertyL(&iProperty);
// ...
CActiveScheduler::Add(this);
iProperty.Subscribe(iStatus);
SetActive();
}
Your RunL will be called when the property has been changed:
void CMyActive::RunL()
{
if (iStatus.Int() != KErrCancel) User::LeaveIfError(iStatus.Int());
// forward the error to RunError
// "To ensure that the subscriber does not miss updates, it should
// re-issue a subscription request before retrieving the current value
// and acting on it." (from docs)
iProperty.Subscribe(iStatus);
TInt value; // this type is passed to RProperty::Define() in the client
TInt err = iProperty.Get(value);
if (err != KErrNotFound) User::LeaveIfError(err);
SetActive();
}
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.