// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OB_MULTI_REQUEST_SENDER_H
#define OB_MULTI_REQUEST_SENDER_H

#include <OB/MultiRequestSender_fwd.h>

#include <OB/NativeTypes.h>
#include <OB/MarshalStubImpl.h>
#include <OB/OBORB.h>

#include <OB/list.h>

namespace OBCORBA
{

class ORB_impl; // For the friend declaration

} // End namespace OBCORBA

namespace OB
{
    
//
// The MultiRequestSender class. ORB::send_multiple_requests() and all
// related operations delegate to this class.
//
class MultiRequestSender : public RefCount, public JTCRecursiveMutex
{
    //
    // Hide copy-constructor and assignment operator
    //
    MultiRequestSender(const MultiRequestSender&);
    void operator=(const MultiRequestSender&);

    OB_STL::list<CORBA::Request_var> deferredRequests_;

    MultiRequestSender() { }
    virtual ~MultiRequestSender() { }
    friend class ::OBCORBA::ORB_impl; // ORB_impl creates MultiRequestSender

public:

    static inline MultiRequestSender_ptr _duplicate(MultiRequestSender_ptr p)
    { if(p) p -> _OB_incRef(); return p; }
    static inline MultiRequestSender_ptr _nil()
    { return 0; }

    //
    // CORBA::ORB delegates to OB::MultiRequestSender, using these
    // operations
    //
    void sendMultipleRequestsOneway(const CORBA::ORB::RequestSeq&);
    void sendMultipleRequestsDeferred(const CORBA::ORB::RequestSeq&);
    CORBA::Boolean pollNextResponse();
    void getNextResponse(CORBA::Request_out);

    //
    // These operations are used by CORBA::Request
    //
    bool findDeferredRequest(CORBA::Request_ptr);
    void addDeferredRequest(CORBA::Request_ptr);
    void removeDeferredRequest(CORBA::Request_ptr);
};

} // End of namespace OB

namespace CORBA
{

inline void
release(OB::MultiRequestSender_ptr p)
{
    if(p)
	p -> _OB_decRef();
}

inline Boolean
is_nil(OB::MultiRequestSender_ptr p)
{
    return p == 0;
}

} // End of namespace CORBA

#endif
