   Mystery Freezing Bug
  Hi, I have a particle effect where multiple particles originate from a single point and move in random directions. Once they disappear they reset to their original point and move in a random direction again and again. Here's the code:MSG msg;memset(&msg,0,sizeof(msg));while( msg.message != WM_QUIT ){// Check if there are messages in the queue.if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){// Process the message.TranslateMessage( &msg );DispatchMessage( &msg );}else{Sleep(0);for (int i=0; i<PARTNUM; i++){if (Timer >= (i*5.0f)){leftstream->Change_Particle(15.0f, (float)(rand()%3));rightstream->Change_Particle(15.0f, (float)(rand()%3));}}if (Timer < ((PARTNUM-1)*5.0f))Timer += 1.0f;// Redraw the effectframe_render();}}After a certain amount of time the program freezes with no error message. The message handler seems to slow down like there's a memory leak but I would of thought I'd get a stack overflow message. Here's a message I get after debugging.[ Msg: Internel CreateMutex call was successful, but indicated that a handle to an already existing named object was returned. ]If anyone has any ideas they would be much appreciated, thanks.
  We need much much more information to answer because this code snippet gives nothing.First, tell us what the variables/symbols you use are. We know nothing about PARTNUM, left/rightstream and what happens in the renderer (frame_render). What about the Timer, why do you stop increasing it after (PARTNUM-1)*5.0f?Why do you call sleep? I don't think it's wise, and 0 as argument probably do nothing.If you think you have an overflow of messages, post your message handling function. Are you sure you return DefWindowProc(hWnd, msg, wParam, lParam) for unhandled messages?About that mutex, it's supposed to be to prevent a resource to be used twice, so it return the first one created instead. Probably a design bug. Check where you might call CreateMutex() or something containing Mutex in your code.Finally, and most important, what happens when you press the "pause" button while debugging your program when it's frozen? This will send you right to the line currently processed. If it makes no sense, check the call stack window and return a few frame before.   ;  Ok, PARTNUM is a constant integer which stores the total number of particles for both streams (25+25=50). The left and rightstream are objects of the particle class, the change_particle function adds to the particles x and y position etc.Timer is there so the particles don't all launch at the same time but split seconds after each other, making a stream rather than a burst. The timer stops when all particles are launched because there's no further reason for it to increase. The particles reset when they disappear so they retain their timings from each other.I don't know why Sleep(0) is there as it was part of the program template before I added to it. I don't think it causes a problem.My message handler does return DefWindowProc(hWnd, msg, wParam, lParam) but here's the function in case I'm missing something:// Basic windows message procedure.LRESULT CALLBACKframe_window_proc(HWND window, UINT msg, WPARAM wp, LPARAM lp){// Used to capture the result of the handling - 0 = All good    LRESULT result = 0;switch (msg){// Application is closed or destroyed.case WM_CLOSE:case WM_DESTROY:PostQuitMessage(0);break;// Application is resized or needs to be repainted.case WM_SIZING:case WM_PAINT:// Calculate the elapsed time since the last update so// that the elapsed time can be used in calculating how// far to progrss animations.CurrentTime = timeGetTime();frame_render();LastTime=timeGetTime();ElapsedTime = LastTime - CurrentTime;char coutput[2048];sprintf(coutput,"Render Time %f\n", ElapsedTime);OutputDebugString(coutput); ValidateRect(window, NULL);break;// A key has been pressed (in this case the escape key to exit).case WM_KEYDOWN:if ( wp == VK_ESCAPE)PostQuitMessage(0);break;default:// Unknown message so pass onto the default message handler.   result = DefWindowProc(window, msg, wp, lp);break;}    return result;}The frame_render function creates the particles with their vertex buffer information etc and then there's another handler (still in frame_render):// Present the scene & handle lost devices.   HRESULT hr = g_device->Present(NULL, NULL, NULL, NULL);while (D3DERR_DEVICELOST == hr)   {  do  { Sleep(0); hr = g_device->TestCooperativeLevel();  }  while (hr != D3DERR_DEVICENOTRESET);  if (FAILED(g_device->Reset(&g_presentation)))  { hr = D3DERR_DEVICELOST;  }   }Now I think this may be where the problem is because when I broke from the program when it froze it was on the line starting HRESULT hr. The hr value is -858993460 and the g_device value is 0x02080060. I'm not sure if this is bad maybe hr being negative is so I should write something to stop it from happening?If any more information is needed please let me know. My particle code is rather vast so I would rather avoid posting it unless it's necessary.   ;  1. What do the debug runtimes say?2. That message loop is wrong - it'll likely cause the app to slow to a crawl and then start behaving oddly. You need to process all outstanding window messages, and then render a frame. If you process a single message, and then rendering a frame causes a message to be produced, or whatever you're doing causes more than one message per frame to be generated, then you'll fill up and eventually overflow your message queue.3. Your window procedure also looks wrong - you should always be passing messages to DefWindowProc, unless you explicitly want to default behaviour not to happen. In your case, all of those messages should end up being passed to DefWindowProc.4. As Dunge said, Sleep(0) is a bad idea. It just causes the current thread to give up the rest of its timeslice to any other threads waiting. Most of the time this will do nothing, and even when it does cause a sleep, it'll be so short that you might as well not have it.   ;  Message loop looks OK to me, a frame update is only being called if PeekMessage says there are no more messages.   ;Quote:Original post by spookycatMessage loop looks OK to me, a frame update is only being called if PeekMessage says there are no more messages.Ah - you're right, I got lost in the indentation there [smile]   ;  Here's the debug runtimes:'sierpinski.exe': Loaded 'E:\My Docs\Port Uni\Year2\AniProg\Particle\Hardware Acceleration2\Debug\sierpinski.exe', Symbols loaded.'sierpinski.exe': Loaded 'C:\Windows\System32\ntdll.dll''sierpinski.exe': Loaded 'C:\Windows\System32\kernel32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\d3d9.dll''sierpinski.exe': Loaded 'C:\Windows\System32\msvcrt.dll''sierpinski.exe': Loaded 'C:\Windows\System32\user32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\gdi32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\advapi32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\rpcrt4.dll''sierpinski.exe': Loaded 'C:\Windows\System32\version.dll''sierpinski.exe': Loaded 'C:\Windows\System32\d3d8thk.dll''sierpinski.exe': Loaded 'C:\Windows\System32\dwmapi.dll''sierpinski.exe': Loaded 'C:\Windows\System32\winmm.dll''sierpinski.exe': Loaded 'C:\Windows\System32\ole32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\oleaut32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\oleacc.dll''sierpinski.exe': Loaded 'C:\Windows\System32\imm32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\msctf.dll''sierpinski.exe': Loaded 'C:\Windows\System32\lpk.dll''sierpinski.exe': Loaded 'C:\Windows\System32\usp10.dll''sierpinski.exe': Loaded 'C:\Windows\System32\eNetHook.dll', Binary was not built with debug information.'sierpinski.exe': Loaded 'C:\Windows\System32\shlwapi.dll''sierpinski.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6001.18000_none_5cdbaa5a083979cc\comctl32.dll'AppInit_DLLs loading eNetHook.dlle:\My Docs\Port Uni\Year2\AniProg\Particle\Hardware Acceleration2\Debug\sierpinski.exesierpinski.exeDLL_PROCESS_ATTACH finished'sierpinski.exe': Loaded 'C:\Windows\System32\uxtheme.dll''sierpinski.exe': Loaded 'C:\Program Files\Common Files\Motive\McciContextHook_DSR.dll''sierpinski.exe': Loaded 'C:\Windows\System32\shell32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\userenv.dll''sierpinski.exe': Loaded 'C:\Windows\System32\secur32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\setupapi.dll''sierpinski.exe': Loaded 'C:\Windows\System32\ntmarta.dll''sierpinski.exe': Loaded 'C:\Windows\System32\Wldap32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\ws2_32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\nsi.dll''sierpinski.exe': Loaded 'C:\Windows\System32\psapi.dll''sierpinski.exe': Loaded 'C:\Windows\System32\samlib.dll'[ DEBUG ][ 05/12/2009 17:32:14 ] [ PID: 4924 ] [ TID: 1940 ] [ McciMT-Log ] [ McciMT::Mutex ] [ Msg: Internel CreateMutex call was successful, but indicated that a handle to an already existing named object was returned. ][ DEBUG ][ 05/12/2009 17:32:14 ] [ PID: 4924 ] [ TID: 1940 ] [ McciMT-Log ] [ McciMT::Mutex ] [ Msg: Internel CreateMutex call was successful, but indicated that a handle to an already existing named object was returned. ]'sierpinski.exe': Loaded 'C:\Windows\System32\nvd3dum.dll'Render Time 47.000000'sierpinski.exe': Loaded 'C:\Windows\System32\clbcatq.dll''sierpinski.exe': Loaded 'C:\Acer\Empowering Technology\ePower\SysHook.dll', Binary was not built with debug information.'sierpinski.exe': Loaded 'C:\Windows\System32\mfc42.dll''sierpinski.exe': Loaded 'C:\Windows\System32\wininet.dll''sierpinski.exe': Loaded 'C:\Windows\System32\normaliz.dll''sierpinski.exe': Loaded 'C:\Windows\System32\urlmon.dll''sierpinski.exe': Loaded 'C:\Windows\System32\iertutil.dll''sierpinski.exe': Loaded 'C:\Windows\System32\odbc32.dll''sierpinski.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.6001.18000_none_886786f450a74a05\comctl32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\comdlg32.dll''sierpinski.exe': Loaded 'C:\Windows\System32\odbcint.dll', Binary was not built with debug information.'sierpinski.exe': Loaded 'C:\Windows\System32\vdmdbg.dll'[ DEBUG ][ 05/12/2009 17:32:15 ] [ PID: 4924 ] [ TID: 1940 ] [ McciMT-Log ] [ McciMT::Thread ] [ Msg: Destructor running, aborting any underlying thread with a deadlock timeout value = 5000 (milliseconds). ]The thread 'Win32 Thread' (0x1f08) has exited with code 0 (0x0).Render Time 15.000000'sierpinski.exe': Loaded 'C:\Program Files\WIDCOMM\Bluetooth Software\BTKeyInd.dll'The program '[4924] sierpinski.exe: Native' has exited with code 0 (0x0).I tried adding the statement 'result = DefWindowProc(window, msg, wp, lp);' to each of the cases in frame_window_proc and I've gotten rid of the Sleep(0) statements. Still having the same problem.   ;  You're not using the debug runtimes there - I can see it loading the release D3D9 DLL, and there's no D3D debug output.The usual window proc looks like:LRESULT CALLBACK frame_window_proc(HWND window, UINT msg, WPARAM wp, LPARAM lp){   switch(msg)   { case WM_FOO: {    // Do any handling here } break;   }   // Always return to DefWindowProc   return DefWindowProc(window, msg, wp, lp);}In particular, your WM_PAINT handler looks dodgy to not call DefWindowProc since there's no BeginPaint() or EndPaint() call (Don't add them, just restructure your window proc).   ;  Hi, Sorry if you thought you were rid of me. I still have the problem but I've tracked down the cause:void Vertex::Buffer(IDirect3DDevice9* device){// Now a vertex buffer needs to be created to contain our one or more vertices.device->CreateVertexBuffer( vertexcount*sizeof(CUSTOMVERTEX),    0 /*Usage*/, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &vertexbuffer, NULL );// Now the vertex is created it needs to be filled with information. This is done// by firstly locking the vertexbuffer, updating, then unlocking the vertexbuffer.void* pVertices;vertexbuffer->Lock( 0, vertexcount*sizeof(CUSTOMVERTEX), (void**)&pVertices, 0 );// Now use memcpy to place the vertex data defined in Step 3 into the vertex buffer.memcpy( pVertices, vertices, vertexcount*sizeof(CUSTOMVERTEX)); // Now the work is done unlock the vertex buffer.vertexbuffer->Unlock();}This is my vertex buffer function and from my experiences in past projects I only needed to call it once. But now I need to call it in a loop so the particles update themselves. So I'm asking is there a way of changing it to work in a loop? I'm guessing there's some sort of memory leak in it if called multiple times.   ;  You don't need to create a new buffer to simply update positions. But are you releasing the vertex-buffer? I mean, that's what the Buffer() function should do:if( NULL != vertexbuffer )    vertexbuffer->release();device->CreateVertexBuffer(...);