jean-frederic clere wrote:
Henri Gomez wrote:
Henri Gomez wrote:
Bill Barker wrote:
----- Original Message ----- From: "Henri Gomez" <[EMAIL PROTECTED]> To: "Tomcat Developers List" <[EMAIL PROTECTED]> Sent: Monday, July 12, 2004 3:07 AM Subject: jk_connect and multi-threading
Hi to all,
I'm looking for a strange problem under iSeries (AS/400) and wonder about this look in jk_open_socket() (jk_connect.c) :
do { jk_log(l, JK_LOG_DEBUG, "jk_open_socket, try to connect socket = %d to %s\n", sock, jk_dump_hinfo(addr, buf));
ret = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)); #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) if(SOCKET_ERROR == ret) { errno = WSAGetLastError() - WSABASEERR; } #endif /* WIN32 */ jk_log(l, JK_LOG_DEBUG, "jk_open_socket, after connect ret = %d\n", ret); } while (-1 == ret && EINTR == errno);
What's the status on errno in multi-threaded environnement ?
On older *nix boxes it wasn't safe to use it with threads. Don't know about
iSeries. On Solaris it's per-thread (assuming that you've compiled
with -D_REENTRANT).
Shouldn't we clear errno before the connect() call ?
It's not supposed to matter.
BTW, I wonder why we check the errno in such case...
Ok, I take a look at IBM errno list and error 3021 is for EINVAL (invalid argument).
I'll investigate this error farther...
The problem could be related to BSD 4.4/Unix 98 where the sa_len should be defined before connect call. May be one of the various reason where
jk_connect failed strangely on many boxes.
Yes, APR uses: +++ apr_status_t apr_socket_connect(apr_socket_t *sock, apr_sockaddr_t *sa) { int rc;
do {
rc = connect(sock->socketdes,
(const struct sockaddr *)&sa->sa.sin,
sa->salen);
} while (rc == -1 && errno == EINTR);
+++
So setting sa_len and USING sa_len instead sizeof(sockaddr_in) in the socket() should fix most of the problems.
From the Rochester Labs documentation, I could read :
http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/index.htm?info/apis/_xopen_source.htm
BSD 4.3 :
typedef int socklen_t; typedef unsigned short sa_family_t;
struct sockaddr { u_short sa_family; char sa_data[14]; };
BSD 4.4 :
typedef int socklen_t; typedef uchar sa_family_t;
struct sockaddr { uint8_t sa_len; sa_family_t sa_family; char sa_data[14]; };
So we should set the sa_len in jk_connect.c when BSD 4.4 / Unix 98 or iSeries using Unix 98. Need info about BSD 4.4 / Unix 98....
int jk_open_socket(struct sockaddr_in *addr, int ndelay, int keepalive, jk_logger_t *l) { char buf[32]; int sock;
jk_log(l, JK_LOG_DEBUG, "Into jk_open_socket\n");
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock > -1) {
int ret;
/* Tries to connect to Tomcat (continues trying while error is EINTR) */
do {
jk_log(l, JK_LOG_DEBUG, "jk_open_socket, try to connect socket = %d to %s\n",
sock, jk_dump_hinfo(addr, buf));
/* Need more infos for BSD 4.4 and Unix 98 defines, for now only iSeries when Unix98 is required at compil time */ #if (_XOPEN_SOURCE >= 520) ((struct sockaddr *)addr)->sa_len = sizeof(struct sockaddr_in)); #endif
ret = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]