diff options
Diffstat (limited to 'pr/src/md/windows/ntio.c')
-rw-r--r-- | pr/src/md/windows/ntio.c | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/pr/src/md/windows/ntio.c b/pr/src/md/windows/ntio.c index defaae4d..03000203 100644 --- a/pr/src/md/windows/ntio.c +++ b/pr/src/md/windows/ntio.c @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Masayuki Nakano <masayuki@d-toybox.com> * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -63,8 +64,10 @@ static PRThread *_pr_io_completion_thread; #define RECYCLE_SIZE 512 static struct _MDLock _pr_recycle_lock; -static PRInt32 _pr_recycle_array[RECYCLE_SIZE]; -static PRInt32 _pr_recycle_tail = 0; +static PRInt32 _pr_recycle_INET_array[RECYCLE_SIZE]; +static PRInt32 _pr_recycle_INET_tail = 0; +static PRInt32 _pr_recycle_INET6_array[RECYCLE_SIZE]; +static PRInt32 _pr_recycle_INET6_tail = 0; __declspec(thread) PRThread *_pr_io_restarted_io = NULL; DWORD _pr_io_restartedIOIndex; /* The thread local storage slot for each @@ -108,6 +111,8 @@ static const PRTime _pr_filetime_offset = 116444736000000000LL; static const PRTime _pr_filetime_offset = 116444736000000000i64; #endif +static PRBool IsPrevCharSlash(const char *str, const char *current); + #define _NEED_351_FILE_LOCKING_HACK #ifdef _NEED_351_FILE_LOCKING_HACK #define _PR_LOCAL_FILE 1 @@ -960,15 +965,20 @@ _PR_MD_INIT_IO() * second argument. */ static SOCKET -_md_get_recycled_socket() +_md_get_recycled_socket(int af) { SOCKET rv; - int af = AF_INET; _MD_LOCK(&_pr_recycle_lock); - if (_pr_recycle_tail) { - _pr_recycle_tail--; - rv = _pr_recycle_array[_pr_recycle_tail]; + if (af == AF_INET && _pr_recycle_INET_tail) { + _pr_recycle_INET_tail--; + rv = _pr_recycle_INET_array[_pr_recycle_INET_tail]; + _MD_UNLOCK(&_pr_recycle_lock); + return rv; + } + if (af == AF_INET6 && _pr_recycle_INET6_tail) { + _pr_recycle_INET6_tail--; + rv = _pr_recycle_INET6_array[_pr_recycle_INET6_tail]; _MD_UNLOCK(&_pr_recycle_lock); return rv; } @@ -986,14 +996,19 @@ _md_get_recycled_socket() * Add a socket to the recycle bin. */ static void -_md_put_recycled_socket(SOCKET newsock) +_md_put_recycled_socket(SOCKET newsock, int af) { - PR_ASSERT(_pr_recycle_tail >= 0); + PR_ASSERT(_pr_recycle_INET_tail >= 0); + PR_ASSERT(_pr_recycle_INET6_tail >= 0); _MD_LOCK(&_pr_recycle_lock); - if (_pr_recycle_tail < RECYCLE_SIZE) { - _pr_recycle_array[_pr_recycle_tail] = newsock; - _pr_recycle_tail++; + if (af == AF_INET && _pr_recycle_INET_tail < RECYCLE_SIZE) { + _pr_recycle_INET_array[_pr_recycle_INET_tail] = newsock; + _pr_recycle_INET_tail++; + _MD_UNLOCK(&_pr_recycle_lock); + } else if (af == AF_INET6 && _pr_recycle_INET6_tail < RECYCLE_SIZE) { + _pr_recycle_INET6_array[_pr_recycle_INET6_tail] = newsock; + _pr_recycle_INET6_tail++; _MD_UNLOCK(&_pr_recycle_lock); } else { _MD_UNLOCK(&_pr_recycle_lock); @@ -1322,7 +1337,7 @@ _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, } } - accept_sock = _md_get_recycled_socket(); + accept_sock = _md_get_recycled_socket(fd->secret->af); if (accept_sock == INVALID_SOCKET) return -1; @@ -1352,7 +1367,7 @@ _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, &bytes, &(me->md.overlapped.overlapped)); - if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING)) { + if ( (rv == 0) && ((err = WSAGetLastError()) != ERROR_IO_PENDING)) { /* Argh! The IO failed */ closesocket(accept_sock); _PR_THREAD_LOCK(me); @@ -1445,7 +1460,7 @@ _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, sd->secret->md.io_model_committed = PR_TRUE; } - *newSock = _md_get_recycled_socket(); + *newSock = _md_get_recycled_socket(sd->secret->af); if (*newSock == INVALID_SOCKET) return -1; @@ -1695,7 +1710,7 @@ _PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd, } if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { - _md_put_recycled_socket(sock->secret->md.osfd); + _md_put_recycled_socket(sock->secret->md.osfd, sock->secret->af); } PR_ASSERT(me->io_pending == PR_FALSE); @@ -2769,7 +2784,7 @@ _PR_MD_OPEN_DIR(_MDDir *d, const char *name) * If 'name' ends in a slash or backslash, do not append * another backslash. */ - if (filename[len - 1] == '/' || filename[len - 1] == '\\') { + if (IsPrevCharSlash(filename, filename + len)) { len--; } strcpy(&filename[len], "\\*.*"); @@ -2907,7 +2922,7 @@ _PR_MD_STAT(const char *fn, struct stat *info) int len = strlen(fn); if (len > 0 && len <= _MAX_PATH - && (fn[len - 1] == '\\' || fn[len - 1] == '/')) { + && IsPrevCharSlash(fn, fn + len)) { char newfn[_MAX_PATH + 1]; strcpy(newfn, fn); @@ -2924,6 +2939,17 @@ _PR_MD_STAT(const char *fn, struct stat *info) #define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') +static PRBool +IsPrevCharSlash(const char *str, const char *current) +{ + const char *prev; + + if (str >= current) + return PR_FALSE; + prev = _mbsdec(str, current); + return (prev == current - 1) && _PR_IS_SLASH(*prev); +} + /* * IsRootDirectory -- * @@ -2970,7 +2996,7 @@ IsRootDirectory(char *fn, size_t buflen) /* look for the next slash */ do { - p++; + p = _mbsinc(p); } while (*p != '\0' && !_PR_IS_SLASH(*p)); if (*p == '\0') { return PR_FALSE; @@ -2984,7 +3010,7 @@ IsRootDirectory(char *fn, size_t buflen) /* look for the final slash */ do { - p++; + p = _mbsinc(p); } while (*p != '\0' && !_PR_IS_SLASH(*p)); if (_PR_IS_SLASH(*p) && p[1] != '\0') { return PR_FALSE; @@ -3074,7 +3100,7 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) info->creationTime = 0; return 0; } - if (!_PR_IS_SLASH(pathbuf[len - 1])) { + if (!IsPrevCharSlash(pathbuf, pathbuf + len)) { _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); return -1; } else { |