I’m developping a TDI Client.
I TdiBuildSetEventHandler(ClientEventReceiveDatagram,…);
In my design,It’s one Producer and one Consumer.
in my InitFunc:
{
//…
//Init a spinlock
//Init a double linklist
KeInitializeSemaphore(pSemaphore,0,1);//count is 0,limit is 1
//…
}
In my EventReceiveDatagramHandler:
{
//…
//copy the datagram to a node
//add the node to a double-linklist, sync by spinlock
KeReleaseSemaphore(pSemaphore,SEMAPHORE_INCREMENT,1,FALSE);//release 1
//…
}
In my worker thread,It will handle the double linklist
{
//…
while (TRUE)
{
//…
KeWaitForSingleObject(pSemaphore, Executive, KernelMode, FALSE, NULL);
//get and remove the oldest node from double-linklist,sync by spinlock
//handle the data fo the node
//…
}
}
In my test,everything is OK.
But,when I read the DDK carefully,I find a problem,it puzzled me.
In document from DDK:
Releasing a semaphore object causes the semaphore count to be augmented by the value of the Adjustment parameter. If the resulting value is greater than the limit of the semaphore object, the count is not adjusted and an exception, STATUS_SEMAPHORE_LIMIT_EXCEEDED, is raised.
oh,my god!It’s not same as classic OS.(I think semaphore’s count has no limit in classic OS).
I think it’s trouble:
My EventReceiveDatagramHandler is called at DPC LEVEL,and my worker thread is in PASSIVE LEVEL.
When there are very many datagram received,my EventReceiveDatagramHandler will be called continually,and my worker thread has no chance to execute?
my EventReceiveDatagramHandler will be called once,and return to the UDP-driver;there are many datagram,so UDP-driver call my EventReceiveDatagramHandler again…my worker thread has no chance to execute.
So,I will KeReleaseSemaphore,and the resulting value is greater than the limit,crash!
But,in my test,everything is OK!
What the key theory?My analyse is right or wrong?
If I’m right,what should I do in this situation?
If I’m wrong,why?
thanks ~I wan to know WHY,not just HOW.Thanks very much~