>
> To understand correctly, we don't propagate such failures (as
> exceptions or error returns), and even if we did, it'd be pointless...


My thinly veiled agenda here is -

We are already toast in this case anyway, can we just get rid of the extra
complexity that comes with trying pretend we can actually reliably do
something under a memory exhaustion case?



On Wed, Jan 28, 2015 at 1:07 PM, Pieter Hintjens <p...@imatix.com> wrote:

> To understand correctly, we don't propagate such failures (as
> exceptions or error returns), and even if we did, it'd be pointless...
>
> FWIW we added quite a lot handling in CZMQ to handle memory
> exhaustion. I don't particularly like that, as it makes things complex
> and it's unclear that there's any practical strategy for apps that hit
> such errors.
>
>
> On Tue, Jan 27, 2015 at 8:25 PM, Thomas Rodgers <rodg...@twrodgers.com>
> wrote:
> > I know sustrik has previously railed on this topic, but at the risk of
> > rehashing some of that ground...
> >
> > My reading of libzmq's source suggests that it goes to some lengths to
> > prevent raising C++ exceptions, which, given that the C API functions do
> not
> > attempt to guard against propagating exceptions to the caller, is a Good
> > Thing. The code in some places uses malloc/free, in others either
> placement
> > new into pre-allocated memory or new (std::nothrow) to prevent
> allocations
> > from throwing. This is all well and good as far as it goes, but it
> doesn't
> > go that far -
> >
> > stream_engine_t, mechanism_t, metadata_t, ctx_t (for example) all use
> > node-based STL containers (std::map, std::mutlimap) which perform
> > allocations on insertion/copy.
> >
> > mechanism_t's ctor default instantiates two std::map<std::string,
> > std::string>'s. Properties are then added to these dictionaries as they
> are
> > consumed from the wire. Each property is stored as a key/value pair of
> > std::string, which may throw on construction if it cannot allocate the
> > requested space, and the insert may throw if it cannot allocate space for
> > the map node.
> >
> > In stream_engine_t::mechanism_read() -
> >
> > It creates a local std::map<std::string, std::string> which it then
> merges
> > properties exchanged from the transport mechanism (zap and zmtp) then
> > constructs a metadata_t with a copy of that merged set. Though
> metadata_t is
> > instantiated as follows -
> >
> > metadata = new (std::nothrow) metadata_t (properties);
> >
> > This can still throw. All std::nothrow guarantees is the allocation of
> space
> > for metadata_t will not throw, it does not guard against metadata_t's
> ctor
> > throwing (which can happen since it takes, and therefore must allocate
> space
> > for, a copy of properties).
> >
> > This is perhaps somewhat academic since, in a low memory situation, you
> are
> > likely hosed anyway (and on Linux you will likely never see an exception
> > because of the OOM killer), but from a design standpoint the library
> > currently has the ability to propagate errors back up the call stack to a
> > client that can, in no way, do anything about them.
> >
> > Should the user facing API wrap and catch any propagated exceptions, and
> > either return some error code or in the std::bad_alloc, do an
> alloc_assert
> > and terminate?
> >
> > Another option that will address this case is to introduce a custom
> > allocator which fails via alloc_assert, and update all STL type
> definitions
> > to use that allocator.
> >
> > _______________________________________________
> > zeromq-dev mailing list
> > zeromq-dev@lists.zeromq.org
> > http://lists.zeromq.org/mailman/listinfo/zeromq-dev
> >
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev@lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
_______________________________________________
zeromq-dev mailing list
zeromq-dev@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to