Changeset 21438 for lang/c

Show
Ignore:
Timestamp:
10/16/08 22:06:44 (5 years ago)
Author:
frsyuki
Message:

lang/c/mpio: mp::iothreads::writer: improved exception safety

Location:
lang/c/mpio/trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • lang/c/mpio/trunk/mp/iothreads/writer.h

    r20594 r21438  
    5454        static void send_datav(int fd, const struct iovec* vb, const reqvec* vr, size_t count); 
    5555 
     56        static void send_datav(int fd, const struct iovec* vb, size_t count, mp::zone& zone, bool thread_safe = false); 
     57 
    5658private: 
    5759        static void send_data_real(int fd, const void* buf, size_t buflen, finalize_t finalize, 
     
    101103        } catch (...) { delete x; throw; } 
    102104 
    103         try { 
    104                 writer::send_data_real(fd, buf, buflen, 
    105                                 &writer::finalize_delete<mp::zone>, 
    106                                 reinterpret_cast<void*>(x), thread_safe); 
    107         } catch (...) { 
    108                 try { 
    109                         x->delegate_to(z); 
    110                 } catch (...) { delete x; throw; } 
    111                 delete x; throw; 
    112         } 
     105        writer::send_data_real(fd, buf, buflen, 
     106                        &writer::finalize_delete<mp::zone>, 
     107                        reinterpret_cast<void*>(x), thread_safe); 
    113108} 
    114109 
     
    138133} 
    139134 
     135inline void send_datav(int fd, const struct iovec* vb, size_t count, mp::zone& z, bool thread_safe = false) 
     136{ 
     137        writer::send_datav(fd, vb, count, z, thread_safe); 
     138} 
     139 
    140140 
    141141}  // namespace iothreads 
  • lang/c/mpio/trunk/mp/zone.pre.h

    r20171 r21438  
    2323 
    2424 
    25  
    2625class zone { 
    2726public: 
     
    3635                T* allocate(MP_ARGS_PARAMS); 
    3736MP_ARGS_END 
     37 
     38 
     39        void* malloc(size_t sz); 
    3840 
    3941 
     
    6062        T* push_object(T* x); 
    6163 
     64        static void finalize_free(void* p); 
     65 
    6266        template <typename T> 
    6367        static void finalize_destruct_free(void* obj); 
  • lang/c/mpio/trunk/mp/zone_impl.pre.h

    r21348 r21438  
    5151{ 
    5252        void (*func)(void*) = &zone::finalize_destruct_free<T>; 
    53         push_finalizer(func, reinterpret_cast<void*>(x)); 
     53        try { 
     54                push_finalizer(func, reinterpret_cast<void*>(x)); 
     55        } catch (...) { (*func)(x); throw; } 
    5456        return x; 
     57} 
     58 
     59inline void* zone::malloc(size_t sz) 
     60{ 
     61        void* p = ::malloc(sz); 
     62        if(!p) { throw std::bad_alloc(); } 
     63        void (*func)(void*) = &zone::finalize_free; 
     64        try { 
     65                push_finalizer(func, p); 
     66        } catch (...) { (*func)(p); throw; } 
     67        return p; 
    5568} 
    5669 
     
    7790} 
    7891 
     92inline void zone::finalize_free(void* p) 
     93{ 
     94        ::free(p); 
     95} 
     96 
    7997template <typename T> 
    8098void zone::finalize_destruct_free(void* obj) 
  • lang/c/mpio/trunk/src/iothreads_writer.cc

    r21348 r21438  
    219219inline void writer::impl::send_data_real(int fd, const void* buf, size_t buflen, finalize_t finalize, 
    220220                void* user, bool thread_safe) 
    221 { 
     221try { 
    222222        if(is_empty(fd)) { 
    223223                ssize_t wl = ::write(fd, buf, buflen); 
     
    247247                add_data(fd, buf, buflen, finalize, user, thread_safe); 
    248248        } 
    249 } 
     249 
     250} catch (...) { 
     251        send_data_prefailed(fd); 
     252        call_finalize(finalize, user); 
     253        throw; 
     254} 
     255 
    250256 
    251257 
     
    266272                } 
    267273 
    268                 size_t i; 
    269                 for(i=0; i < count; ++i) { 
    270                         if(static_cast<size_t>(wl) >= vb[i].iov_len) { 
    271                                 wl -= vb[i].iov_len; 
     274                size_t i = 0; 
     275                try { 
     276                        for(; i < count; ++i) { 
     277                                if(static_cast<size_t>(wl) >= vb[i].iov_len) { 
     278                                        wl -= vb[i].iov_len; 
     279                                        call_finalize(vr[i].finalize, vr[i].user); 
     280                                } else { 
     281                                        add_data(fd, ((const char*)vb[i].iov_base + wl), vb[i].iov_len - wl, 
     282                                                        vr[i].finalize, vr[i].user, vr[i].thread_safe); 
     283                                        ++i; 
     284                                        break; 
     285                                } 
     286                        } 
     287         
     288                        for(; i < count; ++i) { 
     289                                add_data(fd, vb[i].iov_base, vb[i].iov_len, 
     290                                                vr[i].finalize, vr[i].user, vr[i].thread_safe); 
     291                        } 
     292 
     293                } catch (...) { 
     294                        send_data_prefailed(fd); 
     295                        for(; i < count; ++i) { 
    272296                                call_finalize(vr[i].finalize, vr[i].user); 
    273                         } else { 
    274                                 add_data(fd, ((const char*)vb[i].iov_base + wl), vb[i].iov_len - wl, 
    275                                                 vr[i].finalize, vr[i].user, vr[i].thread_safe); 
    276                                 ++i; 
    277                                 break; 
    278                         } 
    279                 } 
    280  
    281                 for(; i < count; ++i) { 
    282                         add_data(fd, vb[i].iov_base, vb[i].iov_len, 
    283                                         vr[i].finalize, vr[i].user, vr[i].thread_safe); 
     297                        } 
     298                        throw; 
    284299                } 
    285300 
    286301        } else { 
    287302add_all: 
    288                 for(size_t i=0; i < count; ++i) { 
    289                         add_data(fd, vb[i].iov_base, vb[i].iov_len, 
    290                                         vr[i].finalize, vr[i].user, vr[i].thread_safe); 
     303                size_t i = 0; 
     304                try { 
     305                        for(; i < count; ++i) { 
     306                                add_data(fd, vb[i].iov_base, vb[i].iov_len, 
     307                                                vr[i].finalize, vr[i].user, vr[i].thread_safe); 
     308                        } 
     309                } catch (...) { 
     310                        send_data_prefailed(fd); 
     311                        for(; i < count; ++i) { 
     312                                call_finalize(vr[i].finalize, vr[i].user); 
     313                        } 
     314                        throw; 
    291315                } 
    292316        } 
     
    294318 
    295319clean_all: 
     320        send_data_prefailed(fd); 
    296321        for(size_t i=0; i < count; ++i) { 
    297322                call_finalize(vr[i].finalize, vr[i].user); 
    298323        } 
    299         send_data_prefailed(fd); 
    300 } 
    301  
     324} 
     325 
     326 
     327void writer::send_datav(int fd, const struct iovec* vb, size_t count, mp::zone& z, bool thread_safe) 
     328{ 
     329        reqvec vr[count]; 
     330 
     331        size_t i; 
     332        for(i=0; i < count-1; ++i) { 
     333                vr[i] = reqvec(&writer::finalize_nothing, NULL); 
     334        } 
     335 
     336        mp::zone* x = new mp::zone(); 
     337        try { 
     338                z.delegate_to(*x); 
     339        } catch (...) { delete x; throw; } 
     340 
     341        vr[i] = reqvec(&writer::finalize_delete<mp::zone>, 
     342                        reinterpret_cast<void*>(x), thread_safe); 
     343 
     344        instance().send_datav(fd, vb, vr, count); 
     345} 
    302346 
    303347