Changeset 21348

Show
Ignore:
Timestamp:
10/15/08 11:41:06 (5 years ago)
Author:
frsyuki
Message:

lang/c/mpio: improved exception handling

Location:
lang/c/mpio/trunk
Files:
1 added
20 modified

Legend:

Unmodified
Added
Removed
  • lang/c/mpio/trunk/Makefile.am

    r19729 r21348  
    1717                mp/event.h \ 
    1818                mp/event_impl.h \ 
     19                mp/exception.h \ 
    1920                mp/fdnotify.h \ 
    2021                mp/fdnotify_impl.h \ 
  • lang/c/mpio/trunk/mp/Makefile

    r21111 r21348  
    6868        $< > $@ 
    6969 
    70 .PHONY: clean 
     70.PHONY: clean install distdir 
    7171clean: 
    7272        $(RM) $(NEED_PREPROCESS) 
    7373 
    74 install: 
    75         # dummy 
    76  
    77 distdir: 
  • lang/c/mpio/trunk/mp/coroutine.h

    r19729 r21348  
    7171        static void join(handler& target) 
    7272                { s_instance->join_impl(target); } 
     73 
     74        //! Return current handler 
     75        static handler& current() 
     76                { return *s_current; } 
    7377 
    7478        //! Resume suspended handler's routine. 
  • lang/c/mpio/trunk/mp/event.pre.h

    r18183 r21348  
    2121 
    2222#include "mp/system/config.h" 
     23#include "mp/exception.h" 
    2324#include "mp/utility.h" 
    2425#include "mp/sparse_array.h" 
  • lang/c/mpio/trunk/mp/fdnotify.h

    r19040 r21348  
    2020#define MP_FDNOTIFY_H__ 
    2121 
    22 #include <sys/types.h> 
    23 #include <sys/uio.h> 
    24 #include <unistd.h> 
    25 #include <stdexcept> 
     22#include "mp/exception.h" 
    2623 
    2724#ifndef MP_FDNOTIFY_VECTOR_SIZE 
    28 #define MP_FDNOTIFY_VECTOR_SIZE 64 
     25#define MP_FDNOTIFY_VECTOR_SIZE 32 
    2926#endif 
    3027 
     
    3229 
    3330 
    34 struct fdnotify_exception : public std::runtime_error { 
    35         fdnotify_exception(const std::string& msg) : 
    36                 std::runtime_error(msg) {} 
     31struct fdnotify_error : system_error { 
     32        fdnotify_error(int errno_, const std::string& msg) : 
     33                system_error(errno_, msg) {} 
    3734}; 
    3835 
  • lang/c/mpio/trunk/mp/fdnotify_impl.h

    r19911 r21348  
    2020#define MP_FDNOTIFY_IMPL_H__ 
    2121 
     22#include <sys/types.h> 
     23#include <sys/uio.h> 
     24#include <unistd.h> 
    2225#include <fcntl.h> 
    2326#include <errno.h> 
     
    3033{ 
    3134        if( ::pipe(m_pipe) < 0 ) { 
    32                 throw fdnotify_exception("can't create pipe"); 
     35                throw fdnotify_error(errno, "can't create pipe"); 
    3336        } 
    3437        if( ::fcntl(m_pipe[0], F_SETFL, O_NONBLOCK) < 0 ) { 
    3538                ::close(m_pipe[0]); 
    3639                ::close(m_pipe[1]); 
    37                 throw fdnotify_exception("can't set non-blocking mode"); 
     40                throw fdnotify_error(errno, "can't set non-blocking mode"); 
    3841        } 
    3942} 
     
    6972                if(len < 0) { 
    7073                        if(errno != EAGAIN && errno != EINTR) { 
    71                                 throw fdnotify_exception("write-side pipe is broken"); 
     74                                throw fdnotify_error(errno, "write-side pipe is broken"); 
    7275                        } 
    7376                } else if(len == 0) { 
    74                         throw fdnotify_exception("write-side pipe is closed"); 
     77                        throw fdnotify_error(errno, "write-side pipe is closed"); 
    7578                } 
    7679        } 
     
    9194                        return false; 
    9295                } else { 
    93                         throw fdnotify_exception("read-side pipe is broken"); 
     96                        throw fdnotify_error(errno, "read-side pipe is broken"); 
    9497                } 
    9598        } else if(len == 0) { 
    96                 throw fdnotify_exception("read-side pipe is closed"); 
     99                throw fdnotify_error(errno, "read-side pipe is closed"); 
    97100        } 
    98101 
  • lang/c/mpio/trunk/mp/iothreads.pre.h

    r21304 r21348  
    6262MP_ARGS_END 
    6363 
    64         static void submit(function<void ()> func);    // FIXME 
     64        static void submit(function<void ()> func); 
    6565 
    6666        static void join(); 
     
    8585        blocking_vector<function<void ()> > m_messages; 
    8686        zone m_zone; 
    87  
    88         typedef std::vector<function<void ()> > messages_t; 
    8987 
    9088private: 
  • lang/c/mpio/trunk/mp/iothreads_impl.pre.h

    r19410 r21348  
    2626 
    2727template <typename ThreadIMPL> 
    28 ThreadIMPL* manager::add_thread() { 
     28inline ThreadIMPL* manager::add_thread() { 
    2929        return instance().add_thread_impl<ThreadIMPL>(); 
    3030} 
     
    3232MP_ARGS_BEGIN 
    3333template <typename ThreadIMPL, MP_ARGS_TEMPLATE> 
    34 ThreadIMPL* manager::add_thread(MP_ARGS_PARAMS) { 
     34inline ThreadIMPL* manager::add_thread(MP_ARGS_PARAMS) { 
    3535        return instance().add_thread_impl<ThreadIMPL>(MP_ARGS_FUNC); 
    3636} 
  • lang/c/mpio/trunk/mp/pthread.h

    r19911 r21348  
    2020#define MP_PTHREAD_H__ 
    2121 
     22#include "mp/exception.h" 
    2223#include <pthread.h> 
    2324#include <signal.h> 
    2425 
    2526namespace mp { 
     27 
     28 
     29struct pthread_error : system_error { 
     30        pthread_error(int errno_, const std::string& msg) : 
     31                system_error(errno_, msg) {} 
     32}; 
    2633 
    2734 
     
    3946private: 
    4047        pthread_t m_thread; 
    41         friend bool operator== (const pthread_thread& x, const pthread_thread& y); 
     48        bool operator== (const pthread_thread& other) const; 
     49        bool operator!= (const pthread_thread& other) const; 
    4250}; 
    43  
    44 bool operator== (const pthread_thread& x, const pthread_thread& y); 
    4551 
    4652 
     
    102108private: 
    103109        struct scoped_sigprocmask { 
    104                 scoped_sigprocmask(const sigset_t& ss) : m_ss(ss) 
    105                         { sigprocmask(SIG_BLOCK, &m_ss, NULL); } 
    106                 ~scoped_sigprocmask() 
    107                         { sigprocmask(SIG_UNBLOCK, &m_ss, NULL); } 
     110                scoped_sigprocmask(const sigset_t& ss); 
     111                ~scoped_sigprocmask(); 
    108112                const sigset_t* get() const { return &m_ss; } 
    109113        private: 
  • lang/c/mpio/trunk/mp/pthread_impl.h

    r19911 r21348  
    2020#define MP_PTHREAD_IMPL_H__ 
    2121 
     22#include <iostream> 
     23#include <typeinfo> 
     24#ifndef MP_NO_CXX_ABI_H 
     25#include <cxxabi.h> 
     26#endif 
     27 
    2228namespace mp { 
    2329 
     
    2632pthread_thread::pthread_thread(IMPL* pimpl) 
    2733{ 
    28         pthread_create(&m_thread, NULL, 
     34        int err = pthread_create(&m_thread, NULL, 
    2935                        &pthread_thread::trampoline<IMPL>, 
    30                         reinterpret_cast<void*>(pimpl) 
    31                         ); 
     36                        reinterpret_cast<void*>(pimpl)); 
     37        if(err) { throw pthread_error(err, "failed to create thread"); } 
    3238} 
    3339 
     
    3743inline void pthread_thread::detach() 
    3844{ 
    39         pthread_detach(m_thread); 
     45        int err = pthread_detach(m_thread); 
     46        if(err) { throw pthread_error(err, "failed to detach thread"); } 
    4047} 
    4148 
     
    4350{ 
    4451        void* ret; 
    45         pthread_join(m_thread, &ret);  // FIXME error 
     52        int err = pthread_join(m_thread, &ret); 
     53        if(err) { throw pthread_error(err, "failed to join thread"); } 
    4654        return ret; 
    4755} 
    4856 
    49 inline bool operator== (const pthread_thread& x, const pthread_thread& y) 
     57inline bool pthread_thread::operator== (const pthread_thread& other) const 
    5058{ 
    51         return pthread_equal(x.m_thread, y.m_thread); 
     59        return pthread_equal(m_thread, other.m_thread); 
     60} 
     61 
     62inline bool pthread_thread::operator!= (const pthread_thread& other) const 
     63{ 
     64        return !(*this == other); 
    5265} 
    5366 
    5467template <typename IMPL> 
    5568void* pthread_thread::trampoline(void* obj) 
    56 { 
    57         // FIXME exception 
     69try { 
    5870        reinterpret_cast<IMPL*>(obj)->operator()(); 
    5971        return NULL;  // FIXME 
     72 
     73} catch (std::exception& e) { 
     74        try { 
     75#ifndef MP_NO_CXX_ABI_H 
     76                int status; 
     77                std::cerr 
     78                        << "thread terminated with throwing an instance of '" 
     79                        << abi::__cxa_demangle(typeid(e).name(), 0, 0, &status) 
     80                        << "'\n" 
     81                        << "  what():  " << e.what() << std::endl; 
     82#else 
     83                std::cerr 
     84                        << "thread terminated with throwing an instance of '" 
     85                        << typeid(e).name() 
     86                        << "'\n" 
     87                        << "  what():  " << e.what() << std::endl; 
     88#endif 
     89        } catch (...) {} 
     90        throw; 
     91 
     92} catch (...) { 
     93        try { 
     94                std::cerr << "thread terminated with throwing an unknown object" << std::endl; 
     95        } catch (...) {} 
     96        throw; 
    6097} 
    6198 
     
    118155 
    119156 
     157inline pthread_signal::scoped_sigprocmask::scoped_sigprocmask(const sigset_t& ss) : 
     158        m_ss(ss) 
     159{ 
     160        if( sigprocmask(SIG_BLOCK, &m_ss, NULL) < 0 ) { 
     161                throw pthread_error(errno, "failed to set sigprocmask"); 
     162        } 
     163} 
     164 
     165inline pthread_signal::scoped_sigprocmask::~scoped_sigprocmask() 
     166{ 
     167        sigprocmask(SIG_UNBLOCK, &m_ss, NULL); 
     168} 
     169 
    120170inline pthread_signal::pthread_signal(const sigset_t& ss, void (*handler)(int)) : 
    121171        m_sigmask(ss), m_handler(handler), m_thread(this) {} 
  • lang/c/mpio/trunk/mp/system/buffered_kqueue_impl.h

    r8088 r21348  
    77system::system() : m_kqfd(kqueue()) 
    88{ 
    9         // FIXME m_kqfd < 0 
     9        if(m_kqfd < 0) { 
     10                throw event_error(errno, "failed to initialize kqueue"); 
     11        } 
    1012} 
    1113 
  • lang/c/mpio/trunk/mp/system/epoll_impl.h

    r18183 r21348  
    1010system::system() : m_epfd(epoll_create(MP_EVENT_EPOLL_MAX_RESULT)) 
    1111{ 
    12         // FIXME m_epfd < 0 
     12        if(m_epfd < 0) { 
     13                throw event_error(errno, "failed to create epoll"); 
     14        } 
    1315} 
    1416 
  • lang/c/mpio/trunk/mp/system/kqueue_impl.h

    r8088 r21348  
    77system::system() : m_kqfd(kqueue()) 
    88{ 
    9         // FIXME m_kqfd < 0 
     9        if(m_kqfd < 0) { 
     10                throw event_error(errno, "failed to initialize kqueue"); 
     11        } 
    1012} 
    1113 
  • lang/c/mpio/trunk/mp/utility.pre.h

    r19729 r21348  
    3737inline void set_nonblock(int fd) 
    3838{ 
    39         // FIXME error 
    40         fcntl(fd, F_SETFL, O_NONBLOCK); 
     39        if( ::fcntl(fd, F_SETFL, O_NONBLOCK) < 0 ) { 
     40                throw system_error(errno, "failed to set nonblock flag"); 
     41        } 
    4142} 
    4243 
     
    153154 
    154155#endif /* mp/utility.h */ 
     156 
  • lang/c/mpio/trunk/mp/zone_impl.pre.h

    r20171 r21348  
    2121 
    2222#include <stdlib.h> 
    23 #include <stdexcept> 
     23#include <new> 
    2424 
    2525namespace mp { 
  • lang/c/mpio/trunk/src/iothreads.cc

    r19410 r21348  
    4646void manager::run_impl() 
    4747{ 
     48        typedef std::vector<function<void ()> > messages_t; 
    4849        messages_t cache; 
    4950        while(!m_end_flag) { 
  • lang/c/mpio/trunk/src/iothreads_connector.cc

    r19911 r21348  
    141141connector::impl::worker::worker() 
    142142{ 
    143         m_ev.add(m_notify.getfd(), EV_READ);  // FIXME error 
     143        if( m_ev.add(m_notify.getfd(), EV_READ) < 0 ) { 
     144                throw event_error(errno, "iothreads connector failed to initialize event notifier"); 
     145        } 
    144146} 
    145147 
     
    178180                if(m_ev.wait(1000) < 0) {   // FIXME 
    179181                        if(errno != EAGAIN && errno != EINTR) { 
    180                                 throw std::runtime_error("connector event failed"); 
     182                                throw event_error(errno, "iothreads connector event failed"); 
    181183                        } 
    182184                } 
  • lang/c/mpio/trunk/src/iothreads_listener.cc

    r19911 r21348  
    118118listener::impl::worker::worker() 
    119119{ 
    120         m_ev.add(m_notify.getfd(), EV_READ, 
    121                         (void (*)(void*, int))NULL, (void*)NULL);  // FIXME error 
     120        if( m_ev.add(m_notify.getfd(), EV_READ, 
     121                        (void (*)(void*, int))NULL, (void*)NULL) < 0 ) { 
     122                throw event_error(errno, "iothreads listener failed to initialize event notifier"); 
     123        } 
    122124} 
    123125 
     
    150152                if(m_ev.wait(1000) < 0) {   // FIXME 
    151153                        if(errno != EAGAIN && errno != EINTR) { 
    152                                 throw std::runtime_error("listener event failed"); 
     154                                throw event_error(errno, "iothreads listener event failed"); 
    153155                        } 
    154156                } 
     
    171173void listener::impl::worker::listen_impl(notify_entry& e) 
    172174{ 
    173         m_ev.add(e.lsock, EV_READ, e.callback, e.obj); 
     175        if( m_ev.add(e.lsock, EV_READ, e.callback, e.obj) < 0 ) { 
     176                throw event_error(errno, "iothreads listener failed to add event"); 
     177        } 
    174178} 
    175179 
  • lang/c/mpio/trunk/src/iothreads_reader.cc

    r21142 r21348  
    6060                                message_t* func; 
    6161                                int fd; 
    62                         } m; 
     62                        } message; 
    6363                } as; 
    6464        }; 
     
    130130reader::impl::worker::worker() 
    131131{ 
    132         m_ev.add(m_notify.getfd(), EV_READ);  // FIXME error 
     132        if( m_ev.add(m_notify.getfd(), EV_READ) < 0 ) { 
     133                throw event_error(errno, "iothreads reader failed to initialize event notifier"); 
     134        } 
    133135} 
    134136 
     
    153155{ 
    154156        notify_entry e = { MESSAGE }; 
    155         e.as.m.func = msg; 
    156         e.as.m.fd = fd; 
     157        e.as.message.func = msg; 
     158        e.as.message.fd = fd; 
    157159        try { 
    158160                m_notify.send(e); 
     
    170172                if(m_ev.wait(1000) < 0) {   // FIXME 
    171173                        if(errno != EAGAIN && errno != EINTR) { 
    172                                 throw std::runtime_error("reader event failed"); 
     174                                throw event_error(errno, "iothreads reader event failed"); 
    173175                        } 
    174176                } 
     
    214216 
    215217        } else {  // e.type == MESSAGE 
    216                 int fd = e.as.m.fd; 
     218                int fd = e.as.message.fd; 
     219                std::auto_ptr<message_t> func(e.as.message.func); 
    217220                if(!m_ev.test(fd)) { return; } 
    218                 message_t* func = e.as.m.func; 
    219                 try { 
    220                         (*func)(*m_ev.data(fd)); 
    221                 } catch (...) { 
    222                         delete func; 
    223                         throw; 
     221                (*func)(*m_ev.data(fd)); 
     222        } 
     223} 
     224 
     225inline void reader::impl::worker::add_handler(handler* h) 
     226{ 
     227        try { 
     228                if( m_ev.add(h->fd(), EV_READ, h) < 0 ) { 
     229                        throw event_error(errno, "iothreads reader failed to add event"); 
    224230                } 
    225                 delete func; 
    226         } 
    227 } 
    228  
    229 inline void reader::impl::worker::add_handler(handler* h) 
    230 { 
    231         try { 
    232                 m_ev.add(h->fd(), EV_READ, h); 
    233231        } catch (...) { 
    234232                ::close(h->fd()); 
  • lang/c/mpio/trunk/src/iothreads_writer.cc

    r21303 r21348  
    185185                struct rlimit rbuf; 
    186186                if(::getrlimit(RLIMIT_NOFILE, &rbuf) < 0) { 
    187                         throw std::runtime_error("getrlimit() failed"); 
     187                        throw system_error(errno, "getrlimit() failed"); 
    188188                } 
    189189 
     
    386386writer::impl::worker::worker() 
    387387{ 
    388         m_ev.add(m_notify.getfd(), EV_READ);  // FIXME error 
     388        if( m_ev.add(m_notify.getfd(), EV_READ) < 0 ) { 
     389                throw event_error(errno, "iothreads writer failed to initialize event notifier"); 
     390        } 
    389391} 
    390392 
     
    414416                if(m_ev.wait(1000) < 0) {   // FIXME 
    415417                        if(errno != EAGAIN && errno != EINTR) { 
    416                                 throw std::runtime_error("writer event failed"); 
     418                                throw event_error(errno, "iothreads writer event failed"); 
    417419                        } 
    418420                } 
     
    469471        impl::wake_io_ebit(e.fd); 
    470472        if(!m_ev.test(e.fd)) { 
    471                 m_ev.add(e.fd, EV_WRITE);  // FIXME error 
     473                if( m_ev.add(e.fd, EV_WRITE) < 0 ) { 
     474                        throw event_error(errno, "iothreads writer failed to add event"); 
     475                } 
    472476        } 
    473477        request req(e.buf, e.buflen, e.finalize, e.user, e.thread_safe);