1
/*============================================================================
3
==============================================================================
4
Implementation of TChannel class: A generic channel over which one can
5
transport a bidirectional stream of bytes.
7
A TChannel is a lot like a POSIX stream socket in "connected" state.
8
============================================================================*/
10
#include <sys/types.h>
17
#include "mallocvar.h"
18
#include "xmlrpc-c/util_int.h"
19
#include "xmlrpc-c/abyss.h"
21
#include "socket_win.h"
23
#include "socket_unix.h"
30
socketOsInit(const char ** const errorP) {
33
SocketWinInit(errorP);
35
SocketUnixInit(errorP);
53
bool ChannelTraceIsActive;
56
ChannelInit(const char ** const errorP) {
61
ChannelTraceIsActive = (getenv("ABYSS_TRACE_CHANNEL") != NULL);
62
if (ChannelTraceIsActive)
63
fprintf(stderr, "Abyss channel layer will trace channel traffic "
64
"due to ABYSS_TRACE_CHANNEL environment variable\n");
78
/* ChannelCreate() is not exported to the Abyss user. It is meant to
79
be used by an implementation-specific TChannel generator which is
80
exported to the Abyss user, e.g. ChannelCreateUnix() in
83
The TChannel generator functions are the _only_ user-accessible
84
functions that are particular to an implementation.
87
static unsigned int const channelSignature = 0x06060B;
90
ChannelCreate(const struct TChannelVtbl * const vtblP,
92
TChannel ** const channelPP) {
99
channelP->implP = implP;
100
channelP->vtbl = *vtblP;
101
channelP->signature = channelSignature;
102
*channelPP = channelP;
104
if (ChannelTraceIsActive)
105
fprintf(stderr, "Created channel %p\n", channelP);
112
ChannelDestroy(TChannel * const channelP) {
114
if (ChannelTraceIsActive)
115
fprintf(stderr, "Destroying channel %p\n", channelP);
117
assert(channelP->signature == channelSignature);
119
channelP->vtbl.destroy(channelP);
121
channelP->signature = 0; /* For debuggability */
129
ChannelWrite(TChannel * const channelP,
130
const unsigned char * const buffer,
132
bool * const failedP) {
134
if (ChannelTraceIsActive)
135
fprintf(stderr, "Writing %u bytes to channel %p\n", len, channelP);
137
(*channelP->vtbl.write)(channelP, buffer, len, failedP);
143
ChannelRead(TChannel * const channelP,
144
unsigned char * const buffer,
146
uint32_t * const bytesReceivedP,
147
bool * const failedP) {
149
if (ChannelTraceIsActive)
150
fprintf(stderr, "Reading %u bytes from channel %p\n", len, channelP);
152
(*channelP->vtbl.read)(channelP, buffer, len, bytesReceivedP, failedP);
158
ChannelWait(TChannel * const channelP,
159
bool const waitForRead,
160
bool const waitForWrite,
161
uint32_t const timems,
162
bool * const readyToReadP,
163
bool * const readyToWriteP,
164
bool * const failedP) {
166
if (ChannelTraceIsActive) {
168
fprintf(stderr, "Waiting %u milliseconds for data from "
169
"channel %p\n", timems, channelP);
171
fprintf(stderr, "Waiting %u milliseconds for channel %p "
172
"to be writable\n", timems, channelP);
174
(*channelP->vtbl.wait)(channelP, waitForRead, waitForWrite, timems,
175
readyToReadP, readyToWriteP, failedP);
181
ChannelInterrupt(TChannel * const channelP) {
183
if (ChannelTraceIsActive)
184
fprintf(stderr, "Interrupting channel waits");
186
(*channelP->vtbl.interrupt)(channelP);
192
ChannelFormatPeerInfo(TChannel * const channelP,
193
const char ** const peerStringP) {
195
(*channelP->vtbl.formatPeerInfo)(channelP, peerStringP);