diff --git a/PyV8.py b/PyV8.py
index e814e38..de025e0 100644
--- a/PyV8.py
+++ b/PyV8.py
@@ -115,7 +115,13 @@ def int_or_nul(value):
     def frames(self):
         return self.parse_stack(self.stackTrace)
 
+
+class JSTimeoutError(Exception):
+    pass
+
+
 _PyV8._JSError._jsclass = JSError
+_PyV8._JSTimeoutError._jsclass = JSTimeoutError
 
 JSObject = _PyV8.JSObject
 JSNull = _PyV8.JSNull
diff --git a/src/Context.cpp b/src/Context.cpp
index 9c515f3..b24e0e4 100644
--- a/src/Context.cpp
+++ b/src/Context.cpp
@@ -50,12 +50,14 @@ void CContext::Expose(void)
                                        py::arg("name") = std::string(),
                                        py::arg("line") = -1,
                                        py::arg("col") = -1,
-                                       py::arg("precompiled") = py::object()))
+                                       py::arg("precompiled") = py::object(),
+                                       py::arg("timeout") = py::long_(0)))
     .def("eval", &CContext::EvaluateW, (py::arg("source"),
                                         py::arg("name") = std::wstring(),
                                         py::arg("line") = -1,
                                         py::arg("col") = -1,
-                                        py::arg("precompiled") = py::object()))
+                                        py::arg("precompiled") = py::object(),
+                                        py::arg("timeout") = py::long_(0)))
 
     .def("enter", &CContext::Enter, "Enter this context. "
          "After entering a context, all code compiled and "
@@ -205,26 +207,78 @@ py::object CContext::GetCalling(void)
     py::object(py::handle<>(boost::python::converter::shared_ptr_to_python<CContext>(CContextPtr(new CContext(calling)))));
 }
 
+static bool EvaluationTimeout = false;
+
+void TerminateEvaluation(int sig)
+{
+    EvaluationTimeout = true;
+    v8::V8::TerminateExecution(v8::Isolate::GetCurrent());
+}
+
+inline void SetupEvaluationAlarmHook(long timeout)
+{
+    EvaluationTimeout = false;
+    signal(SIGALRM, TerminateEvaluation);
+    ualarm((useconds_t)(timeout * 1000), (useconds_t)0);
+}
+
+inline void CheckEvaluationAlarm()
+{
+    signal(SIGALRM, SIG_IGN);
+    ualarm((useconds_t)0, (useconds_t)0);
+    
+    if (EvaluationTimeout)
+    {
+        EvaluationTimeout = false;
+        
+        throw CJavascriptTimeoutException("Javascript evaluation timeout");
+    }
+}
+
 py::object CContext::Evaluate(const std::string& src,
                               const std::string name,
                               int line, int col,
-                              py::object precompiled)
+                              py::object precompiled, long timeout)
 {
   CEngine engine(v8::Isolate::GetCurrent());
 
   CScriptPtr script = engine.Compile(src, name, line, col, precompiled);
 
-  return script->Run();
+  if (timeout > 0)
+  {
+     SetupEvaluationAlarmHook(timeout);
+  }
+  
+  py::object result = script->Run();
+  
+  if (timeout > 0)
+  {
+     CheckEvaluationAlarm();
+  }
+  
+  return result;
 }
 
 py::object CContext::EvaluateW(const std::wstring& src,
                                const std::wstring name,
                                int line, int col,
-                               py::object precompiled)
+                               py::object precompiled, long timeout)
 {
   CEngine engine(v8::Isolate::GetCurrent());
 
   CScriptPtr script = engine.CompileW(src, name, line, col, precompiled);
 
-  return script->Run();
+  if (timeout > 0)
+  {
+     SetupEvaluationAlarmHook(timeout);
+  }
+  
+  py::object result = script->Run();
+  
+  if (timeout > 0)
+  {
+     CheckEvaluationAlarm();
+  }
+  
+  return result;
 }
diff --git a/src/Context.h b/src/Context.h
index 8603ae1..824e7e1 100644
--- a/src/Context.h
+++ b/src/Context.h
@@ -66,9 +66,9 @@ class CContext
   bool HasOutOfMemoryException(void) { v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); return Handle()->HasOutOfMemoryException(); }
 
   py::object Evaluate(const std::string& src, const std::string name = std::string(),
-                      int line = -1, int col = -1, py::object precompiled = py::object());
+                      int line = -1, int col = -1, py::object precompiled = py::object(), long timeout = 0);
   py::object EvaluateW(const std::wstring& src, const std::wstring name = std::wstring(),
-                       int line = -1, int col = -1, py::object precompiled = py::object());
+                       int line = -1, int col = -1, py::object precompiled = py::object(), long timeout = 0);
 
   static py::object GetEntered(void);
   static py::object GetCurrent(void);
diff --git a/src/Exception.cpp b/src/Exception.cpp
index 5944052..c7a6b51 100644
--- a/src/Exception.cpp
+++ b/src/Exception.cpp
@@ -76,6 +76,13 @@ void CJavascriptException::Expose(void)
     ExceptionTranslator::Construct, py::type_id<CJavascriptException>());
 }
 
+void CJavascriptTimeoutException::Expose(void)
+{
+  py::class_<CJavascriptTimeoutException >("_JSTimeoutError", py::no_init);
+    
+  py::register_exception_translator<CJavascriptTimeoutException>(ExceptionTranslator::TranslateTimeout);
+}
+
 CJavascriptStackTracePtr CJavascriptStackTrace::GetCurrentStackTrace(
   v8::Isolate *isolate, int frame_limit, v8::StackTrace::StackTraceOptions options)
 {
@@ -392,6 +399,22 @@ void ExceptionTranslator::Translate(CJavascriptException const& ex)
   }
 }
 
+void ExceptionTranslator::TranslateTimeout(CJavascriptTimeoutException const& ex)
+{
+  CPythonGIL python_gil;
+
+  // Boost::Python doesn't support inherite from Python class,
+  // so, just use some workaround to throw our custom exception
+  //
+  // http://www.language-binding.net/pyplusplus/troubleshooting_guide/exceptions/exceptions.html
+
+  py::object impl(ex);
+  py::object clazz = impl.attr("_jsclass");
+  py::object err = clazz(impl);
+
+  ::PyErr_SetObject(clazz.ptr(), py::incref(err.ptr()));
+}
+
 void *ExceptionTranslator::Convertible(PyObject* obj)
 {
   CPythonGIL python_gil;
diff --git a/src/Exception.h b/src/Exception.h
index d0c9481..2b0a676 100644
--- a/src/Exception.h
+++ b/src/Exception.h
@@ -19,10 +19,12 @@
 #define END_HANDLE_JAVASCRIPT_EXCEPTION if (try_catch.HasCaught()) CJavascriptException::ThrowIf(v8::Isolate::GetCurrent(), try_catch);
 
 class CJavascriptException;
+class CJavascriptTimeoutException;
 
 struct ExceptionTranslator
 {
   static void Translate(CJavascriptException const& ex);
+  static void TranslateTimeout(CJavascriptTimeoutException const& ex);
 
   static void *Convertible(PyObject* obj);
   static void Construct(PyObject* obj, py::converter::rvalue_from_python_stage1_data* data);
@@ -178,3 +180,21 @@ class CJavascriptException : public std::runtime_error
 
   static void Expose(void);
 };
+
+
+class CJavascriptTimeoutException : public std::runtime_error
+{
+public:
+  CJavascriptTimeoutException(const std::string& msg) :
+    std::runtime_error(msg)
+  {
+  }
+  
+  CJavascriptTimeoutException(const CJavascriptTimeoutException& ex)
+    : std::runtime_error(ex.what())
+  {
+  }
+
+  static void Expose(void);
+};
+
diff --git a/src/PyV8.cpp b/src/PyV8.cpp
index a5b15c6..b8665e2 100644
--- a/src/PyV8.cpp
+++ b/src/PyV8.cpp
@@ -12,6 +12,7 @@
 BOOST_PYTHON_MODULE(_PyV8)
 {
   CJavascriptException::Expose();
+  CJavascriptTimeoutException::Expose();
   CWrapper::Expose(); 
   CContext::Expose();
 #ifdef SUPPORT_AST
diff --git a/src/Wrapper.cpp b/src/Wrapper.cpp
index e3d318e..f67e2cf 100644
--- a/src/Wrapper.cpp
+++ b/src/Wrapper.cpp
@@ -15,6 +15,9 @@
 #include "Context.h"
 #include "Utils.h"
 
+#include <unistd.h>
+#include <signal.h>
+
 #define TERMINATE_EXECUTION_CHECK(returnValue) \
   if(v8::V8::IsExecutionTerminating()) { \
     ::PyErr_Clear(); \
@@ -112,12 +115,14 @@ void CWrapper::Expose(void)
     .def("apply", &CJavascriptFunction::ApplyPython,
          (py::arg("self"),
           py::arg("args") = py::list(),
-          py::arg("kwds") = py::dict()),
+          py::arg("kwds") = py::dict(),
+          py::arg("timeout") = py::long_(0)),
           "Performs a function call using the parameters.")
     .def("invoke", &CJavascriptFunction::Invoke,
           (py::arg("args") = py::list(),
-           py::arg("kwds") = py::dict()),
-          "Performs a binding method call using the parameters.")
+           py::arg("kwds") = py::dict(),
+           py::arg("timeout") = py::long_(0)),
+           "Performs a binding method call using the parameters.")
 
     .def("setName", &CJavascriptFunction::SetName)
 
@@ -1656,22 +1661,78 @@ py::object CJavascriptFunction::CreateWithArgs(CJavascriptFunctionPtr proto, py:
   return CJavascriptObject::Wrap(result);
 }
 
-py::object CJavascriptFunction::ApplyJavascript(CJavascriptObjectPtr self, py::list args, py::dict kwds)
+static bool ApplyJavascriptTimeout = false;
+
+void TerminateExecution(int sig)
+{
+    ApplyJavascriptTimeout = true;
+    v8::V8::TerminateExecution(v8::Isolate::GetCurrent());
+}
+
+inline void SetupAlarmHook(long timeout)
+{
+    ApplyJavascriptTimeout = false;
+    signal(SIGALRM, TerminateExecution);
+    ualarm((useconds_t)(timeout * 1000), (useconds_t)0);
+}
+
+inline void CheckAlarm()
+{
+    signal(SIGALRM, SIG_IGN);
+    ualarm((useconds_t)0, (useconds_t)0);
+    
+    if (ApplyJavascriptTimeout)
+    {
+        ApplyJavascriptTimeout = false;
+        
+        throw CJavascriptTimeoutException("Javascript function call timeout");
+    }
+}
+
+py::object CJavascriptFunction::ApplyJavascript(CJavascriptObjectPtr self, py::list args, py::dict kwds, py::long_ timeout)
 {
   CHECK_V8_CONTEXT();
 
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
-
-  return Call(self->Object(), args, kwds);
+  
+  long timeout_ = py::extract<long>(timeout);
+  
+  if (timeout_ > 0)
+  {
+     SetupAlarmHook(timeout_);
+  }
+  
+  py::object result = Call(self->Object(), args, kwds);
+  
+  if (timeout_ > 0)
+  {
+     CheckAlarm();
+  }
+  
+  return result;
 }
 
-py::object CJavascriptFunction::ApplyPython(py::object self, py::list args, py::dict kwds)
+py::object CJavascriptFunction::ApplyPython(py::object self, py::list args, py::dict kwds, py::long_ timeout)
 {
   CHECK_V8_CONTEXT();
 
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
+  
+  long timeout_ = py::extract<long>(timeout);
+  
+  if (timeout_ > 0)
+  {
+     SetupAlarmHook(timeout_);
+  }
 
-  return Call(CPythonObject::Wrap(self)->ToObject(), args, kwds);
+  py::object result = Call(CPythonObject::Wrap(self)->ToObject(), args, kwds);
+  
+  if (timeout_ > 0)
+  {
+     CheckAlarm();
+  }
+  
+  return result;
 }
 
 py::object CJavascriptFunction::Invoke(py::list args, py::dict kwds)
diff --git a/src/Wrapper.h b/src/Wrapper.h
index 646371d..8ccfe9d 100644
--- a/src/Wrapper.h
+++ b/src/Wrapper.h
@@ -191,8 +191,8 @@ class CJavascriptFunction : public CJavascriptObject
   static py::object CallWithArgs(py::tuple args, py::dict kwds);
   static py::object CreateWithArgs(CJavascriptFunctionPtr proto, py::tuple args, py::dict kwds);
 
-  py::object ApplyJavascript(CJavascriptObjectPtr self, py::list args, py::dict kwds);
-  py::object ApplyPython(py::object self, py::list args, py::dict kwds);
+  py::object ApplyJavascript(CJavascriptObjectPtr self, py::list args, py::dict kwds, py::long_ timeout);
+  py::object ApplyPython(py::object self, py::list args, py::dict kwds, py::long_ timeout);
   py::object Invoke(py::list args, py::dict kwds);
 
   const std::string GetName(void) const;