A timeout safeguard advice

[Edit:]
And here is the online version of the calculator :)

http://vector-partition.jacobs-university.de/cgi-bin/calculator

A test of what it can do: enter (x_1+x_2+x_3+x_4)^10 in the entry and click "Go" :) and that is it! [Edit:] The first two entries where it says "A" and "1" - are for later use so please ignore them :)



Hi guys,


I wrote a (soon-to-be) online calculator - one in which you enter a string, say:
(n_1+n_2)^2
and the calculator returns you the resulting simplified expression:
n_1^2+2n_1n_2+n_2^2
The parser is based on helios' explanation: http://www.cplusplus.com/forum/lounge/11845/ .

The online version of the calculator uses apache server+cgi interface. At the moment it is only set-up on my personal computer, but I want to "go live/online".

What is stopping me is that I have no calculation timeout code. My calculator has some rather powerful functions, however, I cannot judge how long those function take to execute.

I want that the calculator, if not done with the computation in some fixed time, say 10 seconds, display a message:

"Dear user, your calculation has taken more than 10 seconds, the maximum allowed running time for the online version. Please use the offline version of the calculator"


What would you do in my place? Also, I want a relatively secure solution, because it will be hosted on the web servers of my university, and I can get in trouble if the webmasters catch me using up a lot of CPU resources.


Just to be more specific, the calculator's code looks like:

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
#include <iostream>
#include <unistd.h> //to call system functions on a Linux machine
#include "polyhedra.h" //(my main functionality)

void getPath(char* path, std::string& output);

int main(int argc, char **argv)
{ std::string inputString, inputPath, tempS;
  std::cin >> inputString;//there are two methods to get information from a CGI form 
//through an apache server: either via std::cin, or via an environment variable
  if (inputString=="")
  { inputString=getenv("QUERY_STRING"); //getenv is a system function declared in <unistd.h>
  }
  getPath(argv[0], inputPath);
  //inputString contains now the user input, which is a cgi form
  //....
  //here I parse the string and carry out the computation
  // ...
  // and finally I return some meaningful information to the user:
  std::cout << "Content-Type: text/html\n\n"; //to tell the Apache server you are returning html text
  std::cout << "<html><head><title>Vector partition calculator</title>";
  std::cout << "<script src=\"/easy/load.js\"></script> "; //to display beautiful formulas I use a free script called mathjs
  //... here I prepare a nice output for the user
  return 0;   // Toavoid Apache errors.
}


Last edited on
So here is how I finally did it:
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
#include <iostream>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>

timeval ComputationStartGlobal, LastMeasureOfCurrentTime;
const double MaxAllowedComputationTime=20;
bool ComputationComplete;

double GetElapsedTimeInSeconds()
{ gettimeofday(&LastMeasureOfCurrentTime, NULL);
  int miliSeconds =(LastMeasureOfCurrentTime.tv_sec- ComputationStartGlobal.tv_sec)*1000+(LastMeasureOfCurrentTime.tv_usec- ComputationStartGlobal.tv_usec)/1000;
  return ((double) miliSeconds)/1000;
}

void* RunTimer(void* ptr)
{ for (; GetElapsedTimeInSeconds()<MaxAllowedComputationTime;)
  { usleep(10000);
    if (ComputationComplete)
      break;
  }
  if (!ComputationComplete)
  { std::cout << "</div><br><br><br>Your computation has taken " << GetElapsedTimeInSeconds() << " seconds so far.";
    std::cout << "<br>The maximum allowed computation time is <b>" << MaxAllowedComputationTime << " seconds</b>. Please use the offline version of the calculator. ";
    std::exit(0);
  } else
    pthread_exit(NULL);
}


int main(int argc, char **argv)
{ gettimeofday(&ComputationStartGlobal, NULL);
  ComputationComplete=false;
  pthread_t TimerThread;
  pthread_create(&TimerThread, NULL,*RunTimer, 0);
  std::string theResult;
  //here I do my computation based on the input described in the original post
  std::cout << "<br>result: " << theResult << "<br>Parsing+evaluation time: " << GetElapsedTimeInSeconds() << " seconds<br>";
  if (GetElapsedTimeInSeconds()>1)
    std::cout << "If your computation takes too long it is probably due to the weak algorithms used for your computation.<br> Feel free to email the author(s) with requests for speed improvement.";
  ComputationComplete=true;
  std::cout.flush();
//some more output to make the html look better. Non-time critical
  return 0;   // Toavoid Apache errors.
}


Last edited on
Topic archived. No new replies allowed.