|
Matthew Faithfull wrote: Hmm, a tricky one. I would consider having the same thread doing the reading and writing, taking it's orders from a queue and prioritising writing over reading.
We considered that but that wouldn't solve the problem: if there is nothing to write, we will read the serial port (even if there is nothing coming in) and the read will return immediately. If there is still nothing to write, we'll read directly again. Thus, we'll have a busy loop that consumes CPU cycles (and which is an above average priority thread, so it will screw everything).
Matthew Faithfull wrote: In other words do the very short timeout read 1 or 2 msecs then if there is anything to write, write it otherwise go around again and do another read or sleep if no read is required.
Well, that's the problem: we don't want to wait for 1 or 2 msec (waiting for the read operation to complete) or to sleep some msec in between.
Matthew Faithfull wrote: Remember on Windows Mobile your reader/writer thread should not have a raised priority if you do this sort of thing or no other thread will ever get a look in as the threading is purely priority based rather than preemptively time sliced.
If the read and write threads are just waiting (like a blocking read), then this problem is automatically solved. And that's exactly what we want to do: give the read and write thread high priority but they just wait until something happen (data has been received or data need to be transmitted).
But I think we found another way to deal with the problem: bu using WaitCommEvent[^]. In the loop that read the port, we simply call this function before the read. Once the function returns, we check if the event was because of data coming in. If that's the case, then we read the data. So, this loop simply waits until data comes in.
|
|
|
|
|
That sounds good and probably simpler than by next suggestion which would have been to check if IOCompletion Ports work on Mobile 5.0. They would allow you to do the same thing.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Cedric Moonen wrote: if anybody knows a way to read and write simeltaneously on the serial port, it will be really appreciated.
To my knowledge this is not possible on Windows Mobile, since you cannot use overlapped I/O.
By not using overlapped I/O the driver has to complete each IRP before it begins executing the next one.
This enforces a synchronous behavior towards the driver and the point of using different threads for reading and writing is lost.
I see two scenarios with two different questions of importance:
1. You're using handshaking so you won't lose any data that is supposed to be received. Writing has priority over reading and your concern would probably be how long you can delay a write request.
2. You're not using handshaking so you may lose data that is supposed to be received unless you read frequently enough. Reading has priority over writing and your concern would probably be how fast you need to read to avoid loss of data.
Suggestion:
I would try having a queue with messages to be sent that is synchronized with a semaphore which the thread that does the reading and writing waits for. When the semaphore is signaled you write the next message and then issue a read request. If the semaphore is not signaled the wait function will timeout.
I would tweak the COMMTIMEOUTS::ReadTotalTimeoutConstant and the timeout value for the wait function to find a suitable balance between reading and writing depending on whether you're using handshaking or not.
I would avoid ::WaitCommEvent() since it requires something to happen on the UART for it to return. If nothing happens your call may result in a deadlock. If your calling thread is preempted after the write request yet before the request issued by ::WaitCommEvent() , all data may have been transmitted and the call may never return.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Hello
Is it possible to know the last date/time when a hard drive / USB flash drive was formatted? Please let me know if there is any tool which can help me do this.
Thanx
|
|
|
|
|
I want to draw on the none-client area(acturely on the title bar).So,I implement the WM_NCPAINT message by OnNcPaint();
But now,I wan to modify the title height to ajust a bitmap.
What should I do?
Thanks.
GOOD LUCK
|
|
|
|
|
Calling OnNcPaint() directly won't work; you must let the system call it so that you know it has invalidated the right area. I'm not sure why it doesn't call your OnNcPaint() handler when going inactive; I suspect it is a bit of a loophole in the MFC framework whereby it doesn't behave consistently.
Perhaps if you tell us why you are trying to paint in this area, we can suggest an alternative approach? Trying to override the system is always erratic at best {:v)
|
|
|
|
|
I want to change the height of the title bar of a dialog.But I don't know how to do.
Thanks.
|
|
|
|
|
|
But I don't know the right step.
Thanks
|
|
|
|
|
Overide the WM_NCCALSIZE, and in the OnNcCalcSize() function, you will get rect of the dialog
pstncsp->rgrc[0]
And that rect contains you present client area. So if you wanne increase the nonclient area, decrease the client area. Say in your case you want to increase the no client area on the top. For that do do as follows..
void MyDlg::OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* pstncsp )
{
CDialog::OnNcCalcSize( bCalcValidRects_i, pstncsp_i );
pstncsp_i->rgrc[0].top += 50;// Increases the non client area by 50
}
|
|
|
|
|
It works well now,Thank you very much.
|
|
|
|
|
Hi everybody,
my application opens some processes via CreateProcess()
If the application is aborted hardly ( over TaskManager ) the
child processes are still running.
Is there a possibility to start the child processes and if there parent is dead,
they will also stop to exist?
Big thanks for help
|
|
|
|
|
Pass the process HANDLE of the parent to the child. Make sure this HANDLE is inheritable and the bInheritHandles argument in your CreateProcess call is set to TRUE . Then the child can use the WaitForSingleObject function to detect if the child parent is dead (and, as its name suggests, wait for this to happen).
-- modified at 20:49 Monday 10th September, 2007
Steve
|
|
|
|
|
Thanks for help
It's more the problem if the Parent-Process dies and the child processes are still living.
If the parent process ( the GUI ) creates 5 new child processes and the windows user kills the
parent process with the TaskManager, so there are still 5 processes running and never be closed.
That's the problem
|
|
|
|
|
The procedure I outlined will do exactly what you want. Here's an example:
-----------------------------------------------
// ParentChild.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <string>
#include <sstream>
#include <algorithm>
#include <memory>
#include <assert.h>
using namespace std;
HANDLE GetInheritableProcessHandle()
{
HANDLE hProcess;
BOOL bOK = DuplicateHandle(
GetCurrentProcess(), // HANDLE hSourceProcessHandle
GetCurrentProcess(), // HANDLE hSourceHandle
GetCurrentProcess(), // HANDLE hTargetProcessHandle
&hProcess, // LPHANDLE lpTargetHandle
SYNCHRONIZE, // DWORD dwDesiredAccess
TRUE, // BOOL bInheritHandle
0 // DWORD dwOptions
);
if (!bOK)
{
return NULL;
}
return hProcess;
}
void SpawnChild()
{
// Get our path.
char Us[MAX_PATH];
GetModuleFileName(NULL, Us, sizeof(Us));
// Get an inheritable process handle for this process.
HANDLE hUs = GetInheritableProcessHandle();
assert(hUs!=NULL);
// Build the command line.
ostringstream oss;
oss << "\"" << Us << "\" " << reinterpret_cast<DWORD>(hUs);
string CommandLine = oss.str();
// Build a mutable version of the command line string.
char *pMutable = new char[CommandLine.length()+1];
const char *pStr = CommandLine.c_str();
memcpy(pMutable, pStr, CommandLine.length()+1);
// Launch the child process.
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.lpTitle = "I am the child!";
PROCESS_INFORMATION pi;
BOOL bOK = CreateProcess(
NULL, // LPCTSTR lpApplicationName
pMutable, // LPTSTR lpCommandLine
NULL, // LPSECURITY_ATTRIBUTES lpProcessAttributes
NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes
TRUE, // BOOL bInheritHandles
CREATE_NEW_CONSOLE, // DWORD dwCreationFlags
NULL, // LPVOID lpEnvironment
NULL, // LPCTSTR lpCurrentDirectory
&si, // LPSTARTUPINFO lpStartupInfo
&pi // LPPROCESS_INFORMATION lpProcessInformation
);
delete [] pMutable; // Free the memory.
CloseHandle(hUs);
if (!bOK)
{
return;
}
// As always, close handles you don't need or are finished with!
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
int main(int argc, char* argv[])
{
if (argc==1)
{
cout << "I am the parent." << endl;
SpawnChild();
cout << "Press any key to exit." << endl;
_getch();
}
else
{
cout << "I am the child." << endl;
// Get the handle to the parent from the command line.
DWORD HandleValue;
istringstream iss(argv[1]);
iss >> HandleValue;
HANDLE hParent = reinterpret_cast<HANDLE>(HandleValue);
// Wait for the parent to exit or be killed.
WaitForSingleObject(hParent, INFINITE);
// Close handles you're finished with.
CloseHandle(hParent);
}
return 0;
}
Steve
|
|
|
|
|
Ok, i see, it kills really the child processes.
But how does it work exactly?
The command, here pMutable, stores the path & exe and a specific number ( dublicated handler ) after it.
Does the child process also die because the dublicated handle is destroyed and the clone-handle
can't no longer exists and kills that way the child process?
Big thanks for you help !!
|
|
|
|
|
The child process isn’t killed; it’s waiting for the parent process to finish (either gracefully of forcefully). A process HANDLE is a waitable object -- it becomes signaled when the process it identifies no longer exists. WaitForSingleObject waits for a waitable object to become signaled. All the DuplicateHandle stuff is to make the HANDLE inheritable so it is inherited by the child (since the bInheritHandles argument passed to CreateProcess is TRUE ). The value passed in the command line is the duplicated HANDLE 's value.
Steve
|
|
|
|
|
Ok, i understand it now.
So i can create a thread which waits till the parent-process is dead and closes then the application.
Otherwise, if the child closes at first, i kill the Thread which waites on the handle.
Big thanks for your great help
|
|
|
|
|
That’s the basic idea. A word of warning: don’t use the TerminateThread function! See here[^] for details. A professional implementation would use the WaitForMultipleObjects function instead of WaitForSingleObject ; one of the objects is the parent's HANDLE and the other an event (see CreateEvent ) that you use to tell the thread to exit gracefully. Your main thread uses the event to signal the other thread to close down and then waits for it to do so using WaitForSingleObject on the thread's HANDLE .
Steve
|
|
|
|
|
Hello
It seems if you create a process in your application using createprocess or any other API and if the parent application gets terminated forcibly (as in your case) the child process will not get terminated. For referenc refer the "Terminating a Process" section of the MSDN. To go to this topic, look into the Remarks section of "CreateProcess" API.
In the "Terminating a Process" it is clearly mentioned as "When the system is terminating a process, it does not terminate any child processes that the process has created."
However in that section they have mentioned a possibility of achieving ur requirement of terminating a child process when the parent application gets terminated.
Thanx
|
|
|
|
|
Thanks for your help
The possibility offered by MSDN won't fix this kind of problem
So i think there is no possibility to work around my problem
|
|
|
|
|
baerten wrote: So i think there is no possibility to work around my problem
I wouldn't go that far. See here[^].
Steve
|
|
|
|
|
i am using dialog ,in that i have an edit control,when ever my dialog displays cursor must be in the edit control,plz help me............
|
|
|
|
|
You can call GotoDlgCtrl() API for that edit to set the focus. If it is in OnInitDialog, you should return FALSE.
- NS -
|
|
|
|
|
ok fine,if it in another function ,wts the processs............
|
|
|
|