Sample Grabber Sink release() issue - ms-media-foundation

I use Sample Grabber Sink in my Media session using most of code from msdn sample.
In OnProcessSample method I memcpy data to media buffer, attach it to MFSample and put this one into main process pointer. Problem is I either get memory leaking or crashes in ntdll.dll
ntdll.dll!#RtlpLowFragHeapFree#8() Unknown
SampleGrabberSink:
OnProcessSample(...)
{
MFCreateMemoryBuffer(dwSampleSize,&tmpBuff);
tmpBuff->Lock(&data,NULL,NULL);
memcpy(data,pSampleBuffer,dwSampleSize); tmpBuff->Unlock();
MFCreateSample(&tmpSample);
tmpSample->AddBuffer(tmpBuff);
while(!(*Free) && (*pSample)!=NULL)
{
Sleep(1);
}
(*Free)=false;
(*pSample)=tmpSample;
(*Free)=true;
SafeRelease(&tmpBuff);
}
in main thread
ReadSample()
{
if(pSample==NULL)
return;
while(!Free)
Sleep(1);
Free=false;
//process sample into dx surface//
SafeRelease(&pSample);
Free=true;
}
//hr checks omitted//
With this code i get that ntdll.dll error after playing few vids.
I also tried to push samples in qeue so OnProcess doesn't have to wait but then some memory havent free after video ended.
(even now it practicaly doesn't wait, Session rate is 1 and main process can read more than 60fps)
EDIT: It was thread synchronization problem. Solved by using critical section thanks to Roman R.

It is not easy to see is from the code snippet, but I suppose you are burning cycles on a streaming thread (you have your callback called on) until a global/shared variable is NULL and then you duplicate a media sample there.
You need to look at synchronization APIs and serialize access to shared variables. You don't do that and eventually either you are accessing freed memory or breaking reference count of COM object.
You need an event set externally when you are ready to accept new buffer from the callback, then the callback sees the event, enters critical section (or, reader/writer lock), does your *pSample magic there, exits from critical section and sets another event indicating availability of a buffer.

Related

Axon Partialy replay, how do i get a TrackingToken for the startPosition for the replay?

I want my Axon replay events, not all but partially.
A full replay is up and running but when i want a partially replay i need a TrackingToken startPosition for the method resetTokens(), my problem is how to get this token for the partial replay?
I tried with GapAwareTracingToken but this does not work.
public void resetTokensWithRestartIndexFor(String trackingEventProcessorName, Long restartIndex) {
eventProcessingConfiguration
.eventProcessorByProcessingGroup(trackingEventProcessorName, TrackingEventProcessor.class)
.filter(trackingEventProcessor -> !trackingEventProcessor.isReplaying())
.ifPresent(trackingEventProcessor -> {
// shutdown this streaming processor
trackingEventProcessor.shutDown();
// reset the tokens to prepare the processor with start index for replay
trackingEventProcessor.resetTokens(GapAwareTrackingToken.newInstance(restartIndex - 1, Collections.emptySortedSet()));
// start the processor to initiate the replay
trackingEventProcessor.start();
});
}
When i use the GapAwareTrackingToken then i get the exception:
[] - Resolved [java.lang.IllegalArgumentException: Incompatible token type provided.]
I see that there is also a GlobalSequenceTrackingToken i can use, but i don't see any documentatieon about when these can/should be used.
The main "challenge" when doing a partial reset, is that you need to be able to tell where to reset to. In Axon, the position in a stream is defined with a TrackingToken.
The source that you read from will provide you with such a token with each event that it provides. However, when you're doing a reset, you probably didn't store the relevant token while you were consuming those events.
You can also create tokens using any StreamableMessageSource. Generally, this is your Event Store, but if you read from other sources, it could be something else, too.
The StreamableMessageSource provides 4 methods to create a token:
createHeadToken - the position at the most recent edge of the stream, where only new events will be read
createTailToken - the position at the very beginning of the stream, allowing you to replay all events.
createTokenAt(Instant) - the most recent position in the stream that will return all events created on or after the given Instant. Note that some events may still have a timestamp earlier than this timestamp, as event creation and event storage isn't guaranteed to be the same.
createTokenSince(Duration) - similar to createTokenAt, but accepting an amount of time to go back.
So in your case, createTokenAt should do the trick.

Can a thread in ASP.NET work keep continue after Response.End?

I want to make a tcp connection to a device and keep continously retrieve data from device. I want to start this with a simple request and keep it working background even Page response completed. Is this possible in asp.net?
Can a thread in ASP.NET work keep continue after Response.End?
Yes, you can if you do not care or do not need the result.
For example, in the following code, you call AddLogAsync and insert a log, but you not care whether insert successful or not.
public Task AddLogAsync(Log log)
{
return Task.Run(() => AddLog(log));
}
private void AddLog(TraceLog traceLog)
{
// Do something here.
}
I want to make a tcp connection to a device and keep continously
retrieve data from device. I want to start this with a simple request
and keep it working. Is this possible in asp.net?
I'm not really understanding above question. After Response.End, you cannot return anything, although you can continue work on something in different thread.

Mysterious EXC_BAD_ACCESS on dispatch_async *serial queue*

I have a location-based app that gets location every 1 second, and saves a batch of the locations at a time to the CoreData DB so as not to make the locations array too large. However, for some reason it crashes with EXC_BAD_ACCESS even though I use dispatch_async on a SERIAL QUEUE:
Created a global serial custom queue like this:
var MyCustomQueue : dispatch_queue_t =
dispatch_queue_create("uniqueID.for.custom.queue", DISPATCH_QUEUE_SERIAL);
in the didUpdateToLocation protocol function, I have this bit of code that saves the latest batch of CLLocation items onto the disk, if the batch size is greater than a preset number:
if(myLocations.count == MAX_LOCATIONS_BUFFER)
{
dispatch_async(MyCustomQueue)
{
for myLocation in self.myLocations
{
// the next line is where it crashes with EXC_BAD_ACCESS
newLocation = NSEntityDescription.insertNewObjectForEntityForName(locationEntityName, inManagedObjectContext: context as NSManagedObjectContext) ;
newLocation.setValue(..)
// all the code to set the attributes
}
appDelegate.saveContext();
dispatch_async(dispatch_get_main_queue()) {
// once the latest batch is saved, empty the in-memory array
self.myLocations = [];
}
}
}
The mystery is, isn't a SERIAL QUEUE supposed to execute all the items on it in order, even though you use dispatch_async (which simply makes the execution concurrent with the MAIN thread, that doesn't touch the SQLite data)?
Notes:
The crash happens at random times...sometimes it'll crash after 0.5 miles, other times after 2 miles, etc.
If I just take out any of the dispatch_async code (just make everything executed in order on the main thread), there is no issue.
You can take a look at this link. Your issue is probably because there is no MOC at the time you are trying to insert item into it.
Core Data : inserting Objects crashed in global queue [ARC - iPhone simulator 6.1]

interrupted system call error when writing to a pipe

In my user space Linux application, I have a thread which communicated to the main process through a pipe. Below is the code
static void _notify_main(int cond)
{
int r;
int tmp = cond;
r = write( _nfy_fd, &tmp, sizeof(tmp) );
ERROR( "write failed: %d. %s\n", r, strerror(r) );
}
Pretty straight forward. It's been working fine for quite a while now. But recently, the write call will fail with "interrupted system call" error after the programme went under some stress test.
Strangely, the stuff actually went through the pipe no problem. Of course I'd still like to go to the bottom of the error message and get rid of it.
Thanks,
The write(2) man page mentions:
Conforming to
SVr4, 4.3BSD, POSIX.1-2001.
Under SVr4 a write may be interrupted and return EINTR at any point, not just before any data is written.
I guess you were just lucky that it didn't occur so far.
If you google just for the "interrupted system call", you will find this thread which tells you to use siginterrupt() to auto-restart the write call.
From http://www.gnu.org/
A signal can arrive and be handled while an I/O primitive such as open
or read is waiting for an I/O device. If the signal handler returns,
the system faces the question: what should happen next?
POSIX specifies one approach: make the primitive fail right away. The
error code for this kind of failure is EINTR. This is flexible, but
usually inconvenient. Typically, POSIX applications that use signal
handlers must check for EINTR after each library function that can
return it, in order to try the call again. Often programmers forget to
check, which is a common source of error.
So you can handle the EINTR error, there is another choice by the way, You can use sigaction to establish a signal handler specifying how that handler should behave. Using the SA_RESTART flag, return from that handler will resume a primitive; otherwise, return from that handler will cause EINTR.
see interrupted primitives

Adobe Air SQLite synchronous busy timeout / SQLite concurrent access / avoid busy loop

this is my first post here. I'm asking because I ran out of clues and I was unable to find anything about this specific issue.
My question is: In Adobe AIR, is there a way to do a synchronous usleep() equivalent (delay execution of 200ms), alternatively is there a way to specify the SQLite busy timeout somewhere?
I have an AIR application which uses the database in synchronous mode because the code cannot cope with the need of events/callbacks in SQL queries.
The database sometimes is accessed from another application, such that it is busy. Hence the execute() of a statement throws SQLerror 3119 detail 2206. In this case the command shall be retried after a short delay.
As there is another application running on the computer I want to try to avoid busy waiting, however I'm stuck with it because of three things:
First, I was unable to find a way to give the SQLConnection a busy timeout value, like it is possible in C with the function sqlite3_busy_timeout()
Second, I was unable to find the equivalent of the C usleep() command in Adobe AIR / Actionscript.
Third, I am unable to use events/timers/callbacks etc. at this location. The SQL execute() must be synchronous because it is called from deeply nested classes and functions in zillion of places all around in the application.
If the application could cope with events/callbacks while doing SQL I would use an asynchronous database anyway, so this problem cannot be solved using events. The retry must be done on the lowest level without using the AIR event processing facility.
The lowest level of code looks like:
private static function retried(fn:Function):void {
var loops:int = 0;
for (;;) {
try {
fn();
if (loops)
trace("database available again, "+loops+" loops");
return;
} catch (e:Error) {
if (e is SQLError && e.errorID==3119) {
if (!loops)
trace("database locked, retrying");
loops++;
// Braindead AIR does not provide a synchronous sleep
// so we busy loop here
continue;
}
trace(e.getStackTrace());
trace(e);
throw e;
}
}
}
One sample use of this function is:
protected static function begin(conn:SQLConnection):void {
retried(function():void{
conn.begin(SQLTransactionLockType.EXCLUSIVE);
});
}
Output of this code is something like:
database locked, retrying
database available again, 5100 loops
Read: The application loops over 500 times a second. I would like to reduce this to 5 loops somehow to reduce CPU load while waiting, because the App shall run on Laptops while on battery.
Thanks.
-Tino

Resources