ulxr_connection.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002           ulxr_connection.cpp  -  provide a connection for rpc-data
00003                              -------------------
00004     begin                : Sun Mar 24 2002
00005     copyright            : (C) 2002-2007 by Ewald Arnold
00006     email                : ulxmlrpcpp@ewald-arnold.de
00007 
00008     $Id: ulxr_connection.cpp 1064 2007-08-19 16:43:41Z ewald-arnold $
00009 
00010  ***************************************************************************/
00011 
00012 /**************************************************************************
00013  *
00014  * This program is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as
00016  * published by the Free Software Foundation; either version 2 of the License,
00017  * or (at your option) any later version.
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program; if not, write to the Free Software
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027  *
00028  ***************************************************************************/
00029 
00030 // #define ULXR_SHOW_TRACE
00031 // #define ULXR_DEBUG_OUTPUT
00032 // #define ULXR_SHOW_READ
00033 // #define ULXR_SHOW_WRITE
00034 // #include <iostream>
00035 
00036 #define ULXR_NEED_EXPORTS
00037 #include <ulxmlrpcpp/ulxmlrpcpp.h>  // always first header
00038 
00039 #include <ctype.h>
00040 #include <cstdlib>
00041 #include <cerrno>
00042 
00043 #ifdef __WIN32__
00044 #include <winsock2.h>
00045 //#include <windows.h>
00046 #endif
00047 
00048 #ifdef __unix__
00049 #include <unistd.h>
00050 #include <netdb.h>
00051 #include <sys/time.h>
00052 #include <sys/socket.h>
00053 
00054 #if defined(ULXR_USE_EPOLL) && defined(HAVE_SYS_EPOLL_H)
00055 #include <sys/epoll.h>
00056 #endif
00057 
00058 #endif
00059 
00060 #include <csignal>
00061 #include <cstdio>
00062 
00063 #include <ulxmlrpcpp/ulxr_connection.h>
00064 #include <ulxmlrpcpp/ulxr_except.h>
00065 #include <ulxmlrpcpp/ulxr_htmlform_handler.h>
00066 
00067 
00068 namespace ulxr {
00069 
00070 
00071 ULXR_API_IMPL(void) Connection::init()
00072 {
00073   setIsConnecting(false);
00074   connector = 0;
00075   ULXR_TRACE(ULXR_PCHAR("init"));
00076   fd_handle = -1;
00077   setTimeout(10);
00078   setConnectionTimeout(0, 0);
00079 #if !defined(__WIN32__) && !defined(_WIN32)
00080   signal (SIGPIPE, SIG_IGN);  // prevent SIGKILL while write()-ing in closing pipe
00081 #endif
00082 }
00083 
00084 
00085 ULXR_API_IMPL0 Connection::Connection()
00086 {
00087   ULXR_TRACE(ULXR_PCHAR("Connection"));
00088   init();
00089 }
00090 
00091 
00092 ULXR_API_IMPL0 Connection::~Connection()
00093 {
00094   ULXR_TRACE(ULXR_PCHAR("~Connection"));
00095   try
00096   {
00097     close();
00098   }
00099   catch(...)
00100   {
00101     // forget exception?
00102   }
00103 //  delete connector;
00104   connector = 0;
00105 }
00106 
00107 
00108 ULXR_API_IMPL(bool) Connection::isOpen() const
00109 {
00110   ULXR_TRACE( ((fd_handle >= 0)  ? ULXR_PCHAR("isOpen: true")
00111                                  : ULXR_PCHAR("isOpen: false")));
00112   return fd_handle >= 0;
00113 }
00114 
00115 
00116 ULXR_API_IMPL(ssize_t) Connection::low_level_write(char const *buff, long len)
00117 {
00118   ULXR_TRACE(ULXR_PCHAR("low_level_write ") << len);
00119 
00120 #ifndef __unix__
00121       return ::send(fd_handle, buff, len, 0);
00122 #else
00123       return ::write(fd_handle, buff, len);
00124 #endif
00125 
00126 }
00127 
00128 
00129 ULXR_API_IMPL(void) Connection::write(char const *buff, long len)
00130 {
00131   ULXR_TRACE(ULXR_PCHAR("write ") << len);
00132   ULXR_DWRITE_WRITE(buff, len);
00133   ULXR_DOUT_WRITE(ULXR_PCHAR(""));
00134 
00135   long written;
00136 
00137   if (buff == 0 || !isOpen())
00138     throw RuntimeException(ApplicationError, ulxr_i18n(ULXR_PCHAR("Precondition failed for write() call")));
00139 
00140   if (len == 0)
00141     return;
00142 
00143 #if defined(ULXR_USE_EPOLL) && defined(HAVE_SYS_EPOLL_H)
00144 
00145 #ifdef __GNUC__
00146 // #warning ("message using epoll()")
00147 #endif
00148 
00149   while (buff != 0 && len > 0)
00150   {
00151     /* Epoll file descriptor */
00152     int epollfd;
00153 
00154     /* epoll register event structure */
00155     struct epoll_event ev_write;
00156     memset(&ev_write,0,sizeof(struct epoll_event));
00157 
00158     /* Create a epoll structure */
00159     if((epollfd = ::epoll_create(1/* Just a tip to the kernel */)) != -1)
00160     {
00161       /* Prepare the event structure to a dummy use of epoll */
00162       ev_write.events = /*EPOLLET |*/ EPOLLOUT;
00163       ev_write.data.ptr = NULL;
00164 
00165       /* Check-return var  */
00166       int ctlresult;
00167 
00168       if((ctlresult = ::epoll_ctl(epollfd, EPOLL_CTL_ADD, fd_handle, &ev_write)) == 0)
00169       {
00170         /* epoll receive event structure */
00171         struct epoll_event ev[1];
00172         memset(&ev[0],0,sizeof(struct epoll_event));
00173 
00174         int toval = -1;
00175         if (getTimeout() != 0)
00176           toval = getTimeout()*1000;
00177 
00178         int waitresult;
00179         while ((waitresult = epoll_wait(epollfd, ev, 1, toval)) < 0)
00180         {
00181           if(errno == EINTR || errno == EAGAIN)
00182             //if was received signal then continue select
00183             continue;
00184           else
00185           {
00186 //            std::cout << "errno " << errno << std::endl;
00187             CppString s = getErrorString(getLastError());
00188             ::close(epollfd);
00189             throw ConnectionException(SystemError,
00190                     ulxr_i18n(ULXR_PCHAR("Could not perform epoll_wait() call within write(): ")) + s, 500);
00191           }
00192         }
00193 
00194         ::close(epollfd);
00195         if(waitresult == 0)
00196         { /* Timeout */
00197           throw ConnectionException(SystemError,
00198                   ulxr_i18n(ULXR_PCHAR("Timeout while attempting to write.")), 500);
00199         }
00200         else
00201         {
00202           if(waitresult == 1)
00203           { /* It is possible write */
00204             if ( (written = low_level_write(buff, len)) < 0)
00205             {
00206               switch(getLastError())
00207               {
00208                 case EAGAIN:
00209                 case EINTR:
00210 #ifdef __unix__
00211                     errno = 0;
00212 #endif
00213                     continue;
00214 
00215                 case EPIPE:
00216                   close();
00217                   throw ConnectionException(TransportError,
00218                           ulxr_i18n(ULXR_PCHAR("Attempt to write to a connection")
00219                         ULXR_PCHAR(" already closed by the peer")), 500);
00220 
00221                 default:
00222                   throw ConnectionException(SystemError,
00223                           ulxr_i18n(ULXR_PCHAR("Could not perform low_level_write() call: ")
00224                         + getErrorString(getLastError())), 500);
00225               }
00226             }
00227             else
00228             {
00229               buff += written;
00230               len -= written;
00231             }
00232           }
00233           else
00234           { /* Should not reach here */
00235             throw ConnectionException(SystemError,
00236                                       ulxr_i18n(ULXR_PCHAR("Problem while attempting to write by epoll.")), 500);
00237           }
00238         }
00239       }
00240       else
00241       {
00242         ::close(epollfd);
00243         throw ConnectionException(SystemError,
00244                 ulxr_i18n(ULXR_PCHAR("Could not perform epoll_ctl() call: ")), 500);
00245       }
00246     }
00247     else
00248     {
00249       throw ConnectionException(SystemError,
00250                                 ulxr_i18n(ULXR_PCHAR("Could not perform epoll_create() call: ")), 500);
00251     }
00252   }
00253 
00254 #else // ULXR_USE_EPOLL
00255 
00256 #ifdef __GNUC__
00257 //#warning ("message using select()")
00258 #endif
00259 
00260   fd_set wfd;
00261   timeval wait;
00262   timeval *pwait = 0;
00263   if (wait.tv_sec != 0)
00264     pwait = &wait;
00265 
00266   while (buff != 0 && len > 0)
00267   {
00268     FD_ZERO(&wfd);
00269     FD_SET((unsigned) fd_handle, &wfd);
00270     int ready;
00271     wait.tv_sec = getTimeout();
00272     wait.tv_usec = 0;
00273     while((ready = select(fd_handle+1, 0, &wfd, 0, pwait)) < 0)
00274     {
00275       if(errno == EINTR || errno == EAGAIN)
00276       {
00277         //if was received signal then continue select
00278         wait.tv_sec = getTimeout();
00279         wait.tv_usec = 0;
00280         continue;
00281       }
00282       else
00283          throw ConnectionException(SystemError,
00284                                 ulxr_i18n(ULXR_PCHAR("Could not perform select() call: "))
00285                                      + getErrorString(getLastError()), 500);
00286     }
00287     if(ready == 0)
00288       throw ConnectionException(SystemError,
00289                                 ulxr_i18n(ULXR_PCHAR("Timeout while attempting to write.")), 500);
00290 
00291     if(FD_ISSET(fd_handle, &wfd))
00292     {
00293       if ( (written = low_level_write(buff, len)) < 0)
00294       {
00295         switch(getLastError())
00296         {
00297           case EAGAIN:
00298           case EINTR:
00299 #ifdef __unix__
00300             errno = 0;
00301 #endif
00302           continue;
00303 
00304           case EPIPE:
00305             close();
00306             throw ConnectionException(TransportError,
00307                                        ulxr_i18n(ULXR_PCHAR("Attempt to write to a connection")
00308                                             ULXR_PCHAR(" already closed by the peer")), 500);
00309           /*break; */
00310 
00311           default:
00312             throw ConnectionException(SystemError,
00313                                       ulxr_i18n(ULXR_PCHAR("Could not perform low_level_write() call: ")
00314                                            + getErrorString(getLastError())), 500);
00315 
00316         }
00317       }
00318       else
00319       {
00320         buff += written;
00321         len -= written;
00322       }
00323     }
00324   }
00325 
00326 
00327 #endif // ULXR_USE_EPOLL
00328 
00329 }
00330 
00331 
00332 ULXR_API_IMPL(bool) Connection::hasPendingInput() const
00333 {
00334   return false;
00335 }
00336 
00337 
00338 ULXR_API_IMPL(ssize_t) Connection::low_level_read(char *buff, long len)
00339 {
00340 #ifndef __unix__
00341     return ::recv(fd_handle, buff, len, 0);
00342 #else
00343     return ::read(fd_handle, buff, len);
00344 #endif
00345 }
00346 
00347 
00348 ULXR_API_IMPL(ssize_t) Connection::read(char *buff, long len)
00349 {
00350   long readed = 0;
00351 
00352   ULXR_TRACE(ULXR_PCHAR("read 1"));
00353 
00354   if (buff == 0 || !isOpen())
00355     throw RuntimeException(ApplicationError,
00356                            ulxr_i18n(ULXR_PCHAR("Precondition failed for read() call")));
00357 
00358   ULXR_TRACE(ULXR_PCHAR("read 2 ") << len);
00359 
00360   if (len <= 0)
00361     return 0;
00362 
00363   ULXR_TRACE(ULXR_PCHAR("read 3"));
00364 
00365 #if !(defined(ULXR_USE_EPOLL) && defined(HAVE_SYS_EPOLL_H))
00366 
00367   fd_set rfd;
00368   timeval wait;
00369   timeval *pwait = 0;
00370   wait.tv_sec = 0;
00371   wait.tv_usec = 0;
00372   if (wait.tv_sec != 0)
00373     pwait = &wait;
00374 
00375   FD_ZERO(&rfd);
00376   FD_SET((unsigned) fd_handle, &rfd);
00377   int ready;
00378 
00379 #endif
00380 
00381   if (hasPendingInput())
00382   {
00383     ULXR_TRACE(ULXR_PCHAR("read 3 pending"));
00384     if( (readed = low_level_read(buff, len)) < 0)
00385     {
00386       throw ConnectionException(SystemError,
00387                                 ulxr_i18n(ULXR_PCHAR("Could not perform read() call on pending input: "))
00388                                 + getErrorString(getLastError()), 500);
00389     }
00390     ULXR_TRACE(ULXR_PCHAR("read pending readed ") + HtmlFormHandler::makeNumber(readed)
00391                 + ULXR_PCHAR(" and wanted ") + HtmlFormHandler::makeNumber(len));
00392   }
00393 
00394 #if defined(ULXR_USE_EPOLL) && defined(HAVE_SYS_EPOLL_H)
00395 
00396   else
00397   {
00398     /* Epoll file descriptor */
00399     int epollfd;
00400 
00401     /* epoll register event structure */
00402     struct epoll_event ev_read;
00403     memset(&ev_read,0,sizeof(struct epoll_event));
00404 
00405     /* Create a epoll structure */
00406     if((epollfd = ::epoll_create(1/* Just a tip to the kernel */)) != -1)
00407     {
00408       /* Prepare the event structure to a dummy use of epoll */
00409       ev_read.events = /*EPOLLET |*/ EPOLLIN;
00410       ev_read.data.ptr = NULL;
00411 
00412       /* Check-return var  */
00413       int ctlresult;
00414 
00415       if((ctlresult = ::epoll_ctl(epollfd, EPOLL_CTL_ADD, fd_handle, &ev_read)) == 0)
00416       {
00417         /* epoll receive event structure */
00418         struct epoll_event ev[1];
00419         memset(&ev[0],0,sizeof(struct epoll_event));
00420 
00421         int toval = -1;
00422         if (getTimeout() != 0)
00423           toval = getTimeout()*1000;
00424 
00425         ULXR_TRACE(ULXR_PCHAR("read epoll"));
00426         int waitresult;
00427         while ((waitresult = epoll_wait(epollfd, ev, 1, toval)) < 0)
00428         {
00429           ULXR_TRACE(ULXR_PCHAR("read epoll err"));
00430           if(errno == EINTR || errno == EAGAIN)
00431             //if was received signal then continue select
00432             continue;
00433           else
00434           {
00435 //            std::cout << "errno " << errno << std::endl;
00436             CppString s = getErrorString(getLastError());
00437             ::close(epollfd);
00438             throw ConnectionException(SystemError,
00439                     ulxr_i18n(ULXR_PCHAR("Could not perform epoll_wait() call within read(): ")) + s, 500);
00440           }
00441         }
00442 
00443         ULXR_TRACE(ULXR_PCHAR("read epoll closing with result ") + HtmlFormHandler::makeNumber(waitresult)
00444                     + ULXR_PCHAR(" and errno ") + HtmlFormHandler::makeNumber(errno));
00445         ::close(epollfd);
00446         if(waitresult == 0)
00447         { /* Timeout */
00448           throw ConnectionException(SystemError,
00449                   ulxr_i18n(ULXR_PCHAR("Timeout after ")) + HtmlFormHandler::makeNumber(toval) + ulxr_i18n(ULXR_PCHAR("ms while attempting to read (using epoll).")), 500);
00450         }
00451         else
00452         {
00453           if(waitresult == 1)
00454           { /* There is data to read */
00455             if( (readed = low_level_read(buff, len)) < 0)
00456             {
00457               throw ConnectionException(SystemError,
00458                                         ulxr_i18n(ULXR_PCHAR("Could not perform read() call: "))
00459                                         + getErrorString(getLastError()), 500);
00460             }
00461             ULXR_TRACE(ULXR_PCHAR("read readed ") + HtmlFormHandler::makeNumber(readed)
00462                         + ULXR_PCHAR(" and wanted ") + HtmlFormHandler::makeNumber(len));
00463           }
00464           else
00465           { /* Should not reach here */
00466             throw ConnectionException(SystemError,
00467                                       ulxr_i18n(ULXR_PCHAR("Problem while attempting to read by epoll.")), 500);
00468           }
00469         }
00470       }
00471       else
00472       {
00473         ::close(epollfd);
00474         throw ConnectionException(SystemError,
00475                                   ulxr_i18n(ULXR_PCHAR("Could not perform epoll_ctl() call: ")), 500);
00476       }
00477     }
00478     else
00479     {
00480       throw ConnectionException(SystemError,
00481                                 ulxr_i18n(ULXR_PCHAR("Could not perform epoll_create() call: ")), 500);
00482     }
00483   }
00484 
00485 #else // ULXR_USE_EPOLL
00486 
00487   else
00488   {
00489     ULXR_TRACE(ULXR_PCHAR("read 3a"));
00490 
00491     wait.tv_sec = getTimeout();
00492     wait.tv_usec = 0;
00493     while((ready = ::select(fd_handle+1, &rfd, 0, 0, pwait)) < 0)
00494     {
00495       ULXR_TRACE(ULXR_PCHAR("read ~select"));
00496       if(errno == EINTR || errno == EAGAIN)
00497       {
00498         //if was received signal then continue select
00499          wait.tv_sec = getTimeout();
00500          wait.tv_usec = 0;
00501          continue;
00502       }
00503 
00504       else
00505       {
00506           ULXR_TRACE(ULXR_PCHAR("read ConnEx"));
00507           throw ConnectionException(SystemError,
00508                                     ulxr_i18n(ULXR_PCHAR("Could not perform select() call: "))
00509                                     + getErrorString(getLastError()), 500);
00510        }
00511     }
00512 
00513     ULXR_TRACE(ULXR_PCHAR("read 4"));
00514     if(ready == 0)
00515       throw ConnectionException(SystemError,
00516                                 ulxr_i18n(ULXR_PCHAR("Timeout while attempting to read (using select).")), 500);
00517 
00518     ULXR_TRACE(ULXR_PCHAR("read 5"));
00519 
00520     if(FD_ISSET(fd_handle, &rfd))
00521     {
00522       while ( (readed = low_level_read(buff, len)) < 0)
00523       {
00524         ULXR_TRACE(ULXR_PCHAR("read 6: ") << getErrorString(getLastError()));
00525         switch(getLastError())
00526         {
00527           case EAGAIN:
00528           case EINTR:
00529   #ifdef __unix__
00530             errno = 0;
00531   #endif
00532           continue;
00533 
00534           default:
00535             throw ConnectionException(SystemError,
00536                                       ulxr_i18n(ULXR_PCHAR("Could not perform read() call: "))
00537                                       + getErrorString(getLastError()), 500);
00538         }
00539       }
00540     }
00541   }
00542 
00543 
00544 #endif // ULXR_USE_EPOLL
00545 
00546   ULXR_TRACE (ULXR_PCHAR("readed ") << readed);
00547   ULXR_DWRITE_READ(buff, readed);
00548 
00549   // have Content-length field and got unexpected EOF?
00550   // otherwise caller gets until EOF
00551   if (readed == 0 /*&& getBytesToRead() >= 0*/)
00552   {
00553     ULXR_TRACE (ULXR_PCHAR("readed == 0"));
00554     close();
00555     throw ConnectionException(TransportError,
00556                                ulxr_i18n(ULXR_PCHAR("Attempt to read from a connection")
00557                                ULXR_PCHAR(" already closed by the peer")), 500);
00558   }
00559 
00560   return readed;
00561 }
00562 
00563 
00564 ULXR_API_IMPL(void) Connection::cut()
00565 {
00566   ULXR_TRACE(ULXR_PCHAR("cut"));
00567   fd_handle = -1;
00568 }
00569 
00570 
00571 ULXR_API_IMPL(void) Connection::close()
00572 {
00573   ULXR_TRACE(ULXR_PCHAR("close"));
00574   if (isOpen())
00575   {
00576 #ifndef __unix__
00577     ULXR_TRACE(ULXR_PCHAR("closesocket"));
00578     ::closesocket(fd_handle);
00579 #else
00580 
00581     int ret;
00582     ULXR_TRACE(ULXR_PCHAR("close"));
00583     do
00584       ret=::close(fd_handle);
00585     while(ret < 0 && (errno == EINTR || errno == EAGAIN));
00586 
00587     if(ret < 0)
00588       throw ConnectionException(TransportError,
00589                                 ULXR_PCHAR("Close failed: ")+getErrorString(getLastError()), 500);
00590 #endif
00591   }
00592   fd_handle = -1;
00593   ULXR_TRACE(ULXR_PCHAR("/close"));
00594 }
00595 
00596 
00597 ULXR_API_IMPL(int) Connection::getLastError()
00598 {
00599 #ifdef __WIN32__
00600     return(GetLastError());
00601 #else
00602     return(errno);
00603 #endif
00604 }
00605 
00606 
00607 ULXR_API_IMPL(CppString) Connection::getErrorString(int err_number)
00608 {
00609 #ifdef __WIN32__
00610     LPSTR lpMsgBuf;
00611     int ok = FormatMessage(
00612         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00613         NULL,
00614         err_number,
00615         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
00616         (LPSTR)&lpMsgBuf,
00617         0,
00618         NULL);
00619 
00620     if (ok != 0 && lpMsgBuf != 0)
00621       return ULXR_GET_STRING(lpMsgBuf);
00622     else
00623     {
00624       char s[40];
00625       CppString errn  = ULXR_GET_STRING(itoa(err_number, s, 10));
00626       return ulxr_i18n(ULXR_PCHAR("Unknown connection problem, Windows error code: #"))+errn;
00627     }
00628 #else
00629     return(getLastErrorString(err_number));
00630 #endif
00631 }
00632 
00633 
00634 ULXR_API_IMPL(int) Connection::getHandle() const
00635 {
00636   return fd_handle;
00637 }
00638 
00639 
00640 ULXR_API_IMPL(void) Connection::setHandle(int handle)
00641 {
00642   fd_handle = handle;
00643 }
00644 
00645 
00646 ULXR_API_IMPL(bool) Connection::isConnecting() const
00647 {
00648   return isconnecting;
00649 }
00650 
00651 
00652 ULXR_API_IMPL(void) Connection::setIsConnecting(bool connecting)
00653 {
00654   isconnecting = connecting;
00655 }
00656 
00657 
00658 ULXR_API_IMPL(void) Connection::doConnect()
00659 {
00660   ULXR_TRACE(ULXR_PCHAR("doConnect"));
00661   if(connector != 0)
00662   {
00663     ULXR_TRACE(ULXR_PCHAR("doConnect call"));
00664     setIsConnecting(true);
00665     try
00666     {
00667       connector->call();
00668     }
00669     catch(...)
00670     {
00671       setIsConnecting(false);
00672       throw;
00673     }
00674     setIsConnecting(false);
00675 }
00676 }
00677 
00678 
00679 ULXR_API_IMPL0 ConnectorWrapperBase::~ConnectorWrapperBase()
00680 {
00681 }
00682 
00683 
00684 ULXR_API_IMPL(void) Connection::setConnector(ConnectorWrapperBase *in_connector)
00685 {
00686   ULXR_TRACE(ULXR_PCHAR("setConnector ") << (void*) in_connector);
00687   connector = in_connector;
00688 }
00689 
00690 
00691 ULXR_API_IMPL(void) Connection::setTimeout(unsigned to_sec)
00692 {
00693   ULXR_TRACE(ULXR_PCHAR("current timeout ") << to_sec);
00694   current_to = to_sec;
00695 }
00696 
00697 
00698 ULXR_API_IMPL(void) Connection::setConnectionTimeout(unsigned def_to_sec, unsigned alive_to_sec)
00699 {
00700   ULXR_TRACE(ULXR_PCHAR("connection timeout ") << def_to_sec << ULXR_PCHAR(" ") << alive_to_sec);
00701   default_to = def_to_sec;
00702   persist_to = alive_to_sec;
00703 }
00704 
00705 
00706 ULXR_API_IMPL(unsigned) Connection::getTimeout() const
00707 {
00708   return current_to;
00709 }
00710 
00711 
00712 ULXR_API_IMPL(unsigned) Connection::getDefaultTimeout() const
00713 {
00714   if (default_to == 0)
00715     return current_to;
00716   else
00717     return default_to;
00718 }
00719 
00720 
00721 ULXR_API_IMPL(unsigned) Connection::getPersistentTimeout() const
00722 {
00723   if (persist_to == 0)
00724     return current_to;
00725   else
00726     return persist_to;
00727 }
00728 
00729 
00730 }  // namespace ulxr

Generated on Sun Aug 19 20:08:57 2007 for ulxmlrpcpp by  doxygen 1.5.1