C++ Procedural Cube Test - Deadlock. All threads blocked

Hello, I’m really new to Panda3D and I’m having some issues while trying to replicate the Procedural Cube example from the demos in C++.

I am getting a “:thread(error): Deadlock! All threads blocked.” runtime error when I use “PT(Geom) square = new Geom(vdata);” and a “Assertion failed: _cache_ref_count > 0” when I use “Geom* square = new Geom(vdata);”. I’m fairly certain I am supposed to be using PT(Geom) on this, but not sure why it is having a Deadlock when creating the geometry. If I remove the PT(Geom) square and the add_primitive calls while returning null, it runs through without any errors or assertion failures.

I am running the following code: (the first is just in case I am initializing something wrong from the beginning).

   

PandaFramework pandaFramework;
   pandaFramework.open_framework(argc, argv);
   pandaFramework.set_window_title("Test for Procedural Cube");
   PT(WindowFramework) windowFrameworkPtr = pandaFramework.open_window();
   if(windowFrameworkPtr == NULL)
      {
	   nout << "ERROR: could not open the WindowFramework." << endl;
	   return 1; // error
      }
Polygon p;
   GeomNode* snode = makeCube();
Geom* makeSquare(int x1, int y1, int z1, int x2, int y2, int z2)
{
	GeomVertexData* vdata = new GeomVertexData("square", GeomVertexFormat::get_v3n3cpt2(), Geom::UH_dynamic);
	GeomVertexWriter* vertex = new GeomVertexWriter(vdata, "vertex");
	GeomVertexWriter* normal = new GeomVertexWriter(vdata, "normal");
	GeomVertexWriter* color = new GeomVertexWriter(vdata, "color");
	GeomVertexWriter* texcoord = new GeomVertexWriter(vdata, "texcoord");

	//make sure we draw the sqaure in the right plane
	if( x1!=x2 )
	{
		vertex->add_data3f(x1, y1, z1);
		vertex->add_data3f(x2, y1, z1);
		vertex->add_data3f(x2, y2, z2);
		vertex->add_data3f(x1, y2, z2);

		normal->add_data3f(myNormalize(LVecBase3f(2*x1-1, 2*y1-1, 2*z1-1)));
		normal->add_data3f(myNormalize(LVecBase3f(2*x2-1, 2*y1-1, 2*z1-1)));
		normal->add_data3f(myNormalize(LVecBase3f(2*x2-1, 2*y2-1, 2*z2-1)));
		normal->add_data3f(myNormalize(LVecBase3f(2*x1-1, 2*y2-1, 2*z2-1)));
	}
	else
	{
		vertex->add_data3f(x1, y1, z1);
		vertex->add_data3f(x2, y2, z1);
		vertex->add_data3f(x2, y2, z2);
		vertex->add_data3f(x1, y1, z2);

		normal->add_data3f(myNormalize(LVecBase3f(2*x1-1, 2*y1-1, 2*z1-1)));
		normal->add_data3f(myNormalize(LVecBase3f(2*x2-1, 2*y2-1, 2*z1-1)));
		normal->add_data3f(myNormalize(LVecBase3f(2*x2-1, 2*y2-1, 2*z2-1)));
		normal->add_data3f(myNormalize(LVecBase3f(2*x1-1, 2*y1-1, 2*z2-1)));
	}

	//#adding different colors to the vertex for visibility
	color->add_data4f(1.0,0.0,0.0,1.0);
	color->add_data4f(0.0,1.0,0.0,1.0);
	color->add_data4f(0.0,0.0,1.0,1.0);
	color->add_data4f(1.0,0.0,1.0,1.0);

	texcoord->add_data2f(0.0, 1.0);
	texcoord->add_data2f(0.0, 0.0);
	texcoord->add_data2f(1.0, 0.0);
	texcoord->add_data2f(1.0, 1.0);

	PT(GeomTriangles) tri1 = new GeomTriangles(Geom::UH_dynamic);
	PT(GeomTriangles) tri2 = new GeomTriangles(Geom::UH_dynamic);

	tri1->add_vertex(0);
	tri1->add_vertex(1);
	tri1->add_vertex(3);

	tri2->add_consecutive_vertices(1,3);

	tri1->close_primitive();
	tri2->close_primitive();

	PT(Geom) square = new Geom(vdata); //OR *... on one I get a refcount assertion, the other does deadlock threads
	square->add_primitive(tri1);
	square->add_primitive(tri2);

	return square;
	return NULL;
}
GeomNode* makeCube()
{
	Geom* square0 = this->makeSquare(-1,-1,-1, 1,-1, 1);
	Geom* square1 = this->makeSquare(-1, 1,-1, 1, 1, 1);
	Geom* square2 = this->makeSquare(-1, 1, 1, 1,-1, 1);
	Geom* square3 = this->makeSquare(-1, 1,-1, 1,-1,-1);
	Geom* square4 = this->makeSquare(-1,-1,-1,-1, 1, 1);
	Geom* square5 = this->makeSquare( 1,-1,-1, 1, 1, 1);
	GeomNode* snode = new GeomNode("square");
	snode->add_geom(square0);
	snode->add_geom(square1);
	snode->add_geom(square2);
	snode->add_geom(square3);
	snode->add_geom(square4);
	snode->add_geom(square5);

	return snode;
}

Any help or hints would be great!

-Thanks! :smiley:

A good night’s sleep helped me. I switched all of my native pointers to PT(.*?) and it worked. I assume what is happening is that the native pointers anywhere in the code will mess up the threads because they can’t track the pointers correctly without the reference counting; so even if the the native pointer is in a different place on the stack, it will still affect it. :laughing: :bulb:

By the way, you have a memory leak because you don’t delete your GeomVertexWriter objects. They are typically stack variables anyway, whereas you allocate them on the heap.