summaryrefslogtreecommitdiff
path: root/pr/src/md/windows/ntio.c
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/md/windows/ntio.c')
-rw-r--r--pr/src/md/windows/ntio.c68
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 {