1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include <Inventor/@Gui@/So@Gui@.h>
#include <Inventor/@Gui@/viewers/So@Gui@ExaminerViewer.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/actions/SoWriteAction.h>
#include <Inventor/SoInput.h>
#include <Inventor/SoOutput.h>
#include <Inventor/SoDB.h>
#include <Inventor/C/threads/thread.h>
#include <Inventor/threads/SbThread.h>
// This application attempts to check if applying an SoWrite action to
// a scenegraph is thread-safe. A scenegraph is read from the file
// specified on the comand line. Each thread applies an SoWriteAction
// on the scene. The idea is that if the input file is big enough,
// each thread will not have time to finsh its write operation before
// the next thread starts.
// Each thread will output an iv file. The contents of this file
// should of course be the same for all the threads. Verify this by
// doing something like:
// $ for i in `seq 2 10`; do
// echo 'diff 1.iv' $i.iv
// diff 1.iv $i.iv;
// done
class thread_data {
public:
SoSeparator * root;
SbString filename;
int thread_number;
};
static void * thread_callback(void * closure)
{
thread_data * data = (thread_data *) closure;
SoOutput out;
SbBool ok = out.openFile(data->filename.getString());
if (!ok) {
fprintf(stderr, "unable to open output file %s\n", data->filename.getString());
return NULL;
}
fprintf(stdout, "start write, thread nr. %i\n", data->thread_number);
SoWriteAction wa(&out);
wa.apply(data->root);
fprintf(stdout, "finished write, thread nr. %i\n", data->thread_number);
return NULL;
}
int main(int argc, char ** argv)
{
if (argc < 2) {
printf("specify an input file\n");
return -1;
}
@WIDGET@ mainwin = So@Gui@::init(argv[0]);
// read scene
SoInput in;
SbBool ok = in.openFile(argv[1]);
if (!ok) {
fprintf(stderr, "unable to open file %s\n", argv[1]);
return -1;
}
SoSeparator * root = SoDB::readAll(&in);
if (!root) {
fprintf(stderr, "unable to read file %s\n", argv[1]);
return -1;
}
root->ref();
// create 10 threads that applies an SoWriteAction to the scene
for (int i = 1; i <= 10; i++) {
thread_data * data = new thread_data;
data->root = root;
data->thread_number = i;
data->filename.sprintf("%i.iv", i);
(void)SbThread::create(thread_callback, data);
}
// throw up a viewer and show the scene while we wait for the
// trheads to finish
// Use one of the convenient SoQt viewer classes.
So@Gui@ExaminerViewer * eviewer = new So@Gui@ExaminerViewer(mainwin);
eviewer->setSceneGraph(root);
eviewer->show();
// Pop up the main window.
So@Gui@::show(mainwin);
// Loop until exit.
So@Gui@::mainLoop();
// Clean up resources.
delete eviewer;
root->unref();
return 0;
}
|