/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved. * */ using System; using System.Collections.Generic; using System.Text; using BerkeleyDB.Internal; namespace BerkeleyDB { /// /// A class representing a channel in Berkeley DB HA replication manager. /// public class DbChannel : IDisposable { private bool isOpen; private DB_CHANNEL channel; private uint timeout; /// /// Close the channel. /// /// /// /// All channels must be closed before the encompassing environment is /// closed. Also, all on-going messaging operations on the channel /// should be allowed to complete before attempting to close the /// channel. /// /// /// After close, regardless of its return, the DbChannel may not be /// accessed again. /// /// public void Close() { isOpen = false; channel.close(0); } /// /// Release the resources held by this object, and close the channel if /// it is still open. /// public void Dispose() { if (isOpen) channel.close(0); channel.Dispose(); GC.SuppressFinalize(this); } /// /// Send a message on the message channel. The message is sent /// asynchronously. The method does not wait for a response before /// returning. It usually completes quickly because it only waits for /// local TCP implementation to accept the bytes into its network data /// buffer. However, this message could block briefly for longer /// messages, and/or if the network data buffer is nearly full. /// It could even block indefinitely if the remote site is slow /// to read. /// /// /// /// To block while waiting for a response from a remote site, use /// instead of this method. /// /// /// The sent message is received and handled at remote sites using a /// message dispatch callback, which is configured using /// . This /// method may be used within the message dispatch callback on the /// remote site to send a reply or acknowledgement for messages that it /// receives and is handling. /// /// /// This method may be used on channels opened to any destination. See /// for a list of /// potential destinations. /// /// /// /// An array of DatabaseEntry objects. Any flags for the DatabaseEntry /// objects are ignored. /// public void SendMessage(DatabaseEntry[] msg) { int size = msg.Length; IntPtr[] dbts = new IntPtr[size]; for (int i = 0; i < size; i++) dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(msg[i])).Handle; channel.send_msg(dbts, (uint)size, 0); } /// /// Send a message on the message channel. The message is sent /// synchronously. The method blocks waiting for a response before /// returning. If a response is not received within the timeout value /// configured for this request, this method returns with an error /// condition. /// /// /// /// To avoid block while waiting for a response from a remote site, /// use /// /// /// The message sent by this method is received and handled at remote /// sites using a message dispatch callback, which is configured using /// /// /// /// /// DatabaseEntry objects array. Any flags for the DatabaseEntry objects /// are ignored. /// /// /// The amount of time that may elapse while this method waits for a /// response from the remote site. The timeout value must be specified /// as an unsigned 32-bit number of microseconds, limiting the maximum /// timeout to roughly 71 minutes. A timeout value of 0 indicates that /// the channel's default timeout value should be used. This default is /// configured using . /// /// The response from remote site public DatabaseEntry SendRequest( DatabaseEntry[] request, uint timeout) { int size = request.Length; IntPtr[] dbts = new IntPtr[size]; for (int i = 0; i < size; i++) dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle; DatabaseEntry response = new DatabaseEntry(); channel.send_request(dbts, (uint)size, response, timeout, 0); return response; } /// /// Send a message on the message channel. The message is sent /// synchronously. The method blocks waiting for a response before /// returning. If a response is not received within the timeout value /// configured for this request, this method returns with an error /// condition. /// /// /// /// To avoid block while waiting for a response from a remote site, /// use /// /// /// The message sent by this method is received and handled at remote /// sites using a message dispatch callback, which is configured using /// /// /// /// /// DatabaseEntry objects array. Any flags for the DatabaseEntry objects /// are ignored. /// /// Size of bulk buffer /// /// The amount of time that may elapse while this method waits for a /// response from the remote site. The timeout value must be specified /// as an unsigned 32-bit number of microseconds, limiting the maximum /// timeout to roughly 71 minutes. A timeout value of 0 indicates that /// the channel's default timeout value should be used. This default is /// configured using . /// /// Multiple responses from the remote site. public MultipleDatabaseEntry SendRequest( DatabaseEntry[] request, int bufferSize, uint timeout) { int size = request.Length; IntPtr[] dbts = new IntPtr[size]; for (int i = 0; i < size; i++) dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle; DatabaseEntry data = new DatabaseEntry(); data.UserData = new byte[bufferSize]; channel.send_request(dbts, (uint)size, data, timeout, DbConstants.DB_MULTIPLE); MultipleDatabaseEntry response = new MultipleDatabaseEntry(data); return response; } /// /// Set the default timeout value. It is used by /// . /// /// /// /// The timeout is the amount of time that may elapse while /// waits for a message response. It must be /// specified as an unsigned 32-bit number of microseconds, limiting the /// maximum timeout to roughly 71 minutes. /// /// public uint Timeout { get { return timeout; } set { channel.set_timeout(timeout); } } internal DbChannel(DB_CHANNEL channel) { this.channel = channel; isOpen = true; timeout = 0; } } }