File: mt-output-attack.cpp.in

package info (click to toggle)
coin3 4.0.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 52,388 kB
  • sloc: cpp: 254,256; ansic: 23,018; makefile: 8,672; sh: 3,141; perl: 1,504; lex: 1,372; lisp: 1,247; pascal: 961; xml: 604; yacc: 388; sed: 68
file content (106 lines) | stat: -rw-r--r-- 2,785 bytes parent folder | download | duplicates (8)
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;
}