Drizzled Public API Documentation

sleep.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  * Copyright (C) 2009 Sun Microsystems, Inc.
00005  *
00006  * Authors:
00007  *
00008  * Patrick Galbraith <pat@patg.net>
00009  *
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; version 2 of the License.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00023  */
00024  
00025 #include <config.h>
00026 
00027 #include <unistd.h>
00028 #include <time.h>
00029 
00030 #include <drizzled/session.h>
00031 #include <drizzled/item/func.h>
00032 #include <drizzled/internal/my_pthread.h>
00033 #include <drizzled/function/str/strfunc.h>
00034 #include <drizzled/plugin/function.h>
00035 
00036 #include <string>
00037 
00038 using namespace std;
00039 using namespace drizzled;
00040 
00041 
00042 class Item_func_sleep : public Item_int_func
00043 {
00044   /* for thread-safe sleep() */
00045   pthread_mutex_t LOCK_sleep;
00046 
00047 public:
00048   int64_t val_int();
00049   Item_func_sleep() : Item_int_func()
00050   {
00051     unsigned_flag= true;
00052   }
00053 
00054   const char *func_name() const
00055   {
00056     return "sleep";
00057   }
00058 
00059   void fix_length_and_dec()
00060   {
00061     max_length= 1;
00062   }
00063 
00064   bool check_argument_count(int n)
00065   {
00066     return (n == 1);
00067   }
00068 
00069 };
00070 
00071 int64_t Item_func_sleep::val_int()
00072 {
00073   /* int time in seconds, decimal allowed */
00074   double dtime;
00075 
00076   Session &session(getSession());
00077 
00078   if ((arg_count != 1) || ! (dtime= args[0]->val_real()))
00079   {
00080     null_value= true;
00081     return 0;
00082   }
00083 
00084   /*
00085     On 64-bit OSX pthread_cond_timedwait() waits forever
00086     if passed abstime time has already been exceeded by 
00087     the system time.
00088     When given a very short timeout (< 10 mcs) just return 
00089     immediately.
00090     We assume that the lines between this test and the call 
00091     to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
00092   */
00093   if (dtime < 0.00001)
00094     return 0;
00095 
00096   {
00097     boost::this_thread::restore_interruption dl(session.getThreadInterupt());
00098 
00099     try {
00100       boost::xtime xt; 
00101       xtime_get(&xt, boost::TIME_UTC); 
00102       xt.nsec += (uint64_t)(dtime * 1000000000ULL); 
00103       session.getThread()->sleep(xt);
00104     }
00105     catch(boost::thread_interrupted const& error)
00106     {
00107       my_error(drizzled::ER_QUERY_INTERRUPTED, MYF(0));
00108       null_value= true;
00109 
00110       return 0;
00111     }
00112   }
00113 
00114 
00115   null_value= false;
00116 
00117   return (int64_t) 0;
00118 }
00119 
00120 static int sleep_plugin_init(drizzled::module::Context &context)
00121 {
00122   context.add(new plugin::Create_function<Item_func_sleep>("sleep"));
00123 
00124   return 0;
00125 }
00126 
00127 DRIZZLE_PLUGIN(sleep_plugin_init, NULL, NULL);