Re: [msysGit] Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-20 Thread Erik Faye-Lund
On Tue, May 20, 2014 at 10:46 AM, Thomas Braun
 wrote:
> Am 19.05.2014 22:29, schrieb Erik Faye-Lund:
>>>  [...]
>>> Would we need to wrap both ends, shouldn't wrapping only reading be
>>> good enough to prevent deadlocking?
>>>
>>> compat/poll/poll.c already contains a function called IsSocketHandle
>>> that is able to tell if a HANDLE points to a socket or not.
>>
>> This very quick attempt did not work out :(
>>
>> diff --git a/compat/mingw.c b/compat/mingw.c
>> index 0335958..ec1d81f 100644
>> --- a/compat/mingw.c
>> +++ b/compat/mingw.c
>> @@ -370,6 +370,65 @@ int mingw_open (const char *filename, int oflags, ...)
>>   return fd;
>>   }
>>
>> +#define is_console_handle(h) (((long) (h) & 3) == 3)
>> +
>> +static int is_socket_handle(HANDLE h)
>> +{
>> +WSANETWORKEVENTS ev;
>> +
>> +if (is_console_handle(h))
>> +return 0;
>> +
>> +/*
>> + * Under Wine, it seems that getsockopt returns 0 for pipes too.
>> + * WSAEnumNetworkEvents instead distinguishes the two correctly.
>> + */
>> +ev.lNetworkEvents = 0xDEADBEEF;
>> +WSAEnumNetworkEvents((SOCKET) h, NULL, &ev);
>> +return ev.lNetworkEvents != 0xDEADBEEF;
>> +}
>> +
>> +#undef read
>> +ssize_t mingw_read(int fd, void *buf, size_t count)
>> +{
>> +int ret;
>> +HANDLE fh = (HANDLE)_get_osfhandle(fd);
>> +
>> +if (fh == INVALID_HANDLE_VALUE) {
>> +errno = EBADF;
>> +return -1;
>> +}
>> +
>> +if (!is_socket_handle(fh))
>> +return read(fd, buf, count);
>> +
>> +ret = recv((SOCKET)fh, buf, count, 0);
>> +if (ret < 0)
>> +errno = WSAGetLastError();
>> +return ret;
>> +}
>> +
>> +#undef write
>> +ssize_t mingw_write(int fd, const void *buf, size_t count)
>> +{
>> +int ret;
>> +HANDLE fh = (HANDLE)_get_osfhandle(fd);
>> +
>> +if (fh == INVALID_HANDLE_VALUE) {
>> +errno = EBADF;
>> +return -1;
>> +}
>> +
>> +if (!is_socket_handle(fh))
>> +return write(fd, buf, count);
>> +
>> +return send((SOCKET)fh, buf, count, 0);
>> +if (ret < 0)
>> +errno = WSAGetLastError();
>> +return ret;
>> +}
>> +
>> +
>>   static BOOL WINAPI ctrl_ignore(DWORD type)
>>   {
>>   return TRUE;
>> diff --git a/compat/mingw.h b/compat/mingw.h
>> index 08b83fe..1690098 100644
>> --- a/compat/mingw.h
>> +++ b/compat/mingw.h
>> @@ -177,6 +177,12 @@ int mingw_rmdir(const char *path);
>>   int mingw_open (const char *filename, int oflags, ...);
>>   #define open mingw_open
>>
>> +ssize_t mingw_read(int fd, void *buf, size_t count);
>> +#define read mingw_read
>> +
>> +ssize_t mingw_write(int fd, const void *buf, size_t count);
>> +#define write mingw_write
>> +
>>   int mingw_fgetc(FILE *stream);
>>   #define fgetc mingw_fgetc
>
> According to [1] you also have to pass WSA_FLAG_OVERLAPPED to avoid the 
> deadlock.
>
> With that change I don't get a hang anymore but a read error with
> errno 10054 aka WSAECONNRESET.
>
> [1]: https://groups.google.com/forum/#!msg/msysgit/at8D7J-h7mw/PM9w-d41cDYJ
>

Yeah, sorry, I noticed this right after sending and tested with that
as well. My results were the same :/
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [msysGit] Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-20 Thread Thomas Braun
Am 19.05.2014 22:29, schrieb Erik Faye-Lund:
>>  [...]
>> Would we need to wrap both ends, shouldn't wrapping only reading be
>> good enough to prevent deadlocking?
>>
>> compat/poll/poll.c already contains a function called IsSocketHandle
>> that is able to tell if a HANDLE points to a socket or not.
>
> This very quick attempt did not work out :(
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 0335958..ec1d81f 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -370,6 +370,65 @@ int mingw_open (const char *filename, int oflags, ...)
>   return fd;
>   }
>
> +#define is_console_handle(h) (((long) (h) & 3) == 3)
> +
> +static int is_socket_handle(HANDLE h)
> +{
> +WSANETWORKEVENTS ev;
> +
> +if (is_console_handle(h))
> +return 0;
> +
> +/*
> + * Under Wine, it seems that getsockopt returns 0 for pipes too.
> + * WSAEnumNetworkEvents instead distinguishes the two correctly.
> + */
> +ev.lNetworkEvents = 0xDEADBEEF;
> +WSAEnumNetworkEvents((SOCKET) h, NULL, &ev);
> +return ev.lNetworkEvents != 0xDEADBEEF;
> +}
> +
> +#undef read
> +ssize_t mingw_read(int fd, void *buf, size_t count)
> +{
> +int ret;
> +HANDLE fh = (HANDLE)_get_osfhandle(fd);
> +
> +if (fh == INVALID_HANDLE_VALUE) {
> +errno = EBADF;
> +return -1;
> +}
> +
> +if (!is_socket_handle(fh))
> +return read(fd, buf, count);
> +
> +ret = recv((SOCKET)fh, buf, count, 0);
> +if (ret < 0)
> +errno = WSAGetLastError();
> +return ret;
> +}
> +
> +#undef write
> +ssize_t mingw_write(int fd, const void *buf, size_t count)
> +{
> +int ret;
> +HANDLE fh = (HANDLE)_get_osfhandle(fd);
> +
> +if (fh == INVALID_HANDLE_VALUE) {
> +errno = EBADF;
> +return -1;
> +}
> +
> +if (!is_socket_handle(fh))
> +return write(fd, buf, count);
> +
> +return send((SOCKET)fh, buf, count, 0);
> +if (ret < 0)
> +errno = WSAGetLastError();
> +return ret;
> +}
> +
> +
>   static BOOL WINAPI ctrl_ignore(DWORD type)
>   {
>   return TRUE;
> diff --git a/compat/mingw.h b/compat/mingw.h
> index 08b83fe..1690098 100644
> --- a/compat/mingw.h
> +++ b/compat/mingw.h
> @@ -177,6 +177,12 @@ int mingw_rmdir(const char *path);
>   int mingw_open (const char *filename, int oflags, ...);
>   #define open mingw_open
>
> +ssize_t mingw_read(int fd, void *buf, size_t count);
> +#define read mingw_read
> +
> +ssize_t mingw_write(int fd, const void *buf, size_t count);
> +#define write mingw_write
> +
>   int mingw_fgetc(FILE *stream);
>   #define fgetc mingw_fgetc

According to [1] you also have to pass WSA_FLAG_OVERLAPPED to avoid the 
deadlock.

With that change I don't get a hang anymore but a read error with 
errno 10054 aka WSAECONNRESET.

[1]: https://groups.google.com/forum/#!msg/msysgit/at8D7J-h7mw/PM9w-d41cDYJ

diff --git a/compat/mingw.c b/compat/mingw.c
index 383cafe..4a58135 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -366,6 +366,71 @@ int mingw_open (const char *filename, int oflags, ...)
return fd;
 }
 
+#define is_console_handle(h) (((long) (h) & 3) == 3)
+
+static int is_socket_handle(HANDLE h)
+{
+WSANETWORKEVENTS ev;
+
+if (is_console_handle(h))
+return 0;
+
+/*
+ * Under Wine, it seems that getsockopt returns 0 for pipes too.
+ * WSAEnumNetworkEvents instead distinguishes the two correctly.
+ */
+ev.lNetworkEvents = 0xDEADBEEF;
+WSAEnumNetworkEvents((SOCKET) h, NULL, &ev);
+return ev.lNetworkEvents != 0xDEADBEEF;
+}
+
+#undef read
+ssize_t mingw_read(int fd, void *buf, size_t count)
+{
+int ret;
+HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+if (fh == INVALID_HANDLE_VALUE) {
+errno = EBADF;
+return -1;
+}
+
+if (!is_socket_handle(fh))
+return read(fd, buf, count);
+
+ret = recv((SOCKET)fh, buf, count, 0);
+if (ret < 0)
+{
+errno = WSAGetLastError();
+warning("errno %d",errno);
+}
+return ret;
+}
+
+#undef write
+ssize_t mingw_write(int fd, const void *buf, size_t count)
+{
+int ret;
+HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+if (fh == INVALID_HANDLE_VALUE) {
+errno = EBADF;
+return -1;
+}
+
+if (!is_socket_handle(fh))
+return write(fd, buf, count);
+
+ret = send((SOCKET)fh, buf, count, 0);
+if (ret < 0)
+{
+errno = WSAGetLastError();
+warning("errno %d",errno);
+}
+return ret;
+}
+
+
 static BOOL WINAPI ctrl_ignore(DWORD type)
 {
return TRUE;
@@ -1542,7 +1607,7 @@ int mingw_socket(int domain, int type, int protocol)
SOCKET s;
 
ensure_socket_initialization();
-   s = WSASocket(domain, type, protocol, NULL, 0, 0);
+   s = WSASocket(domain, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET) {
/*
 * WSAGetLastError() values are regular BSD error codes
diff --git a/compat/mingw.h b/compat/

Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-19 Thread Erik Faye-Lund
On Mon, May 19, 2014 at 11:15 PM, Thomas Braun
 wrote:
> Am 19.05.2014 21:33, schrieb Jonathan Nieder:
>
>> Hi,
>>
>> Thomas Braun wrote:
>>
>>> pushing over the dump git protocol with a windows git client.
>>
>>
>> I've never heard of the dump git protocol.  Do you mean the git
>> protocol that's used with git:// URLs?
>
>
> You are right I mean the protocol involving git:// URLs. But unfortunately I
> got it wrong as according to [1] the git:// is one of the so-called smart
> protocols. That was also the source where I read that there are smart and
> dump protocols.
>
> [1]: http://git-scm.com/book/en/Git-Internals-Transfer-Protocols
>
>
>> [...]
>>>
>>> Alternative approaches considered but deemed too invasive:
>>> - Rewrite read/write wrappers in mingw.c in order to distinguish between
>>>a file descriptor which has a socket behind and a file descriptor
>>>which has a file behind.
>>
>>
>> I assume here "too invasive" means "too much engineering effort"?
>>
>> It sounds like a clean fix, not too invasive at all.  But I can
>> understand wanting a stopgap in the meantime.
>
>
> No actually I meant too invasive in the sense of "requiring large rewrites
> which only benefit git on windows and hurt all others".
>
> The two fixes I can think of either involve:
> - In a read *and* write wrapper the need to check if the fd is a socket, if
> yes use send/recv if no use read/write. According to Erik's comments this
> should be possible. But I would deem the expected performance penalty quite
> large as that will be done in every call.

You clearly haven't stepped through MSVCRT's read and write implementations :P

I wouldn't worry too much about this, at least not until the numbers are in.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-19 Thread Thomas Braun

Am 19.05.2014 21:33, schrieb Jonathan Nieder:

Hi,

Thomas Braun wrote:


pushing over the dump git protocol with a windows git client.


I've never heard of the dump git protocol.  Do you mean the git
protocol that's used with git:// URLs?


You are right I mean the protocol involving git:// URLs. But 
unfortunately I got it wrong as according to [1] the git:// is one of 
the so-called smart protocols. That was also the source where I read 
that there are smart and dump protocols.


[1]: http://git-scm.com/book/en/Git-Internals-Transfer-Protocols


[...]

Alternative approaches considered but deemed too invasive:
- Rewrite read/write wrappers in mingw.c in order to distinguish between
   a file descriptor which has a socket behind and a file descriptor
   which has a file behind.


I assume here "too invasive" means "too much engineering effort"?

It sounds like a clean fix, not too invasive at all.  But I can
understand wanting a stopgap in the meantime.


No actually I meant too invasive in the sense of "requiring large 
rewrites which only benefit git on windows and hurt all others".


The two fixes I can think of either involve:
- In a read *and* write wrapper the need to check if the fd is a socket, 
if yes use send/recv if no use read/write. According to Erik's comments 
this should be possible. But I would deem the expected performance 
penalty quite large as that will be done in every call.
- Rewriting read/write to accept windows handles instead of file 
descriptors. Only a theoretical option IMHO.


For me the goal is also to minimise the diff between git and msysgit/git.




- Turning the capability side-band-64k off completely. This would remove a 
useful
   feature for users of non-affected transport protocols.


Would it make sense to turn off sideband unconditionally on Windows
when using the relevant protocols?



Yes, if this would be also acceptable for git.git.

I can check at the call site of send_pack in transport.c what protocol 
is in use, and then pass a new parameter use_sideband to it.
Or maybe "adapt" server_capabilities in connect.c to not include 
side-band-64k if using git:// ?



--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [msysGit] Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-19 Thread Erik Faye-Lund
On Mon, May 19, 2014 at 10:00 PM, Erik Faye-Lund  wrote:
> On Mon, May 19, 2014 at 9:33 PM, Jonathan Nieder  wrote:
>> Hi,
>>
>> Thomas Braun wrote:
>>
>>> pushing over the dump git protocol with a windows git client.
>>
>> I've never heard of the dump git protocol.  Do you mean the git
>> protocol that's used with git:// URLs?
>>
>> [...]
>>> Alternative approaches considered but deemed too invasive:
>>> - Rewrite read/write wrappers in mingw.c in order to distinguish between
>>>   a file descriptor which has a socket behind and a file descriptor
>>>   which has a file behind.
>>
>> I assume here "too invasive" means "too much engineering effort"?
>>
>> It sounds like a clean fix, not too invasive at all.  But I can
>> understand wanting a stopgap in the meantime.
>>
>
> Yeah, now that the problem seems to be understood, I don't think that
> would be too bad. I recently killed off our previous write()-wrapper
> in c9df6f4, but I see no reason why we can't add a new one.
>
> Would we need to wrap both ends, shouldn't wrapping only reading be
> good enough to prevent deadlocking?
>
> compat/poll/poll.c already contains a function called IsSocketHandle
> that is able to tell if a HANDLE points to a socket or not.

This very quick attempt did not work out :(

diff --git a/compat/mingw.c b/compat/mingw.c
index 0335958..ec1d81f 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -370,6 +370,65 @@ int mingw_open (const char *filename, int oflags, ...)
 return fd;
 }

+#define is_console_handle(h) (((long) (h) & 3) == 3)
+
+static int is_socket_handle(HANDLE h)
+{
+WSANETWORKEVENTS ev;
+
+if (is_console_handle(h))
+return 0;
+
+/*
+ * Under Wine, it seems that getsockopt returns 0 for pipes too.
+ * WSAEnumNetworkEvents instead distinguishes the two correctly.
+ */
+ev.lNetworkEvents = 0xDEADBEEF;
+WSAEnumNetworkEvents((SOCKET) h, NULL, &ev);
+return ev.lNetworkEvents != 0xDEADBEEF;
+}
+
+#undef read
+ssize_t mingw_read(int fd, void *buf, size_t count)
+{
+int ret;
+HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+if (fh == INVALID_HANDLE_VALUE) {
+errno = EBADF;
+return -1;
+}
+
+if (!is_socket_handle(fh))
+return read(fd, buf, count);
+
+ret = recv((SOCKET)fh, buf, count, 0);
+if (ret < 0)
+errno = WSAGetLastError();
+return ret;
+}
+
+#undef write
+ssize_t mingw_write(int fd, const void *buf, size_t count)
+{
+int ret;
+HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+if (fh == INVALID_HANDLE_VALUE) {
+errno = EBADF;
+return -1;
+}
+
+if (!is_socket_handle(fh))
+return write(fd, buf, count);
+
+return send((SOCKET)fh, buf, count, 0);
+if (ret < 0)
+errno = WSAGetLastError();
+return ret;
+}
+
+
 static BOOL WINAPI ctrl_ignore(DWORD type)
 {
 return TRUE;
diff --git a/compat/mingw.h b/compat/mingw.h
index 08b83fe..1690098 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -177,6 +177,12 @@ int mingw_rmdir(const char *path);
 int mingw_open (const char *filename, int oflags, ...);
 #define open mingw_open

+ssize_t mingw_read(int fd, void *buf, size_t count);
+#define read mingw_read
+
+ssize_t mingw_write(int fd, const void *buf, size_t count);
+#define write mingw_write
+
 int mingw_fgetc(FILE *stream);
 #define fgetc mingw_fgetc
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [msysGit] Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-19 Thread Erik Faye-Lund
On Mon, May 19, 2014 at 9:33 PM, Jonathan Nieder  wrote:
> Hi,
>
> Thomas Braun wrote:
>
>> pushing over the dump git protocol with a windows git client.
>
> I've never heard of the dump git protocol.  Do you mean the git
> protocol that's used with git:// URLs?
>
> [...]
>> Alternative approaches considered but deemed too invasive:
>> - Rewrite read/write wrappers in mingw.c in order to distinguish between
>>   a file descriptor which has a socket behind and a file descriptor
>>   which has a file behind.
>
> I assume here "too invasive" means "too much engineering effort"?
>
> It sounds like a clean fix, not too invasive at all.  But I can
> understand wanting a stopgap in the meantime.
>

Yeah, now that the problem seems to be understood, I don't think that
would be too bad. I recently killed off our previous write()-wrapper
in c9df6f4, but I see no reason why we can't add a new one.

Would we need to wrap both ends, shouldn't wrapping only reading be
good enough to prevent deadlocking?

compat/poll/poll.c already contains a function called IsSocketHandle
that is able to tell if a HANDLE points to a socket or not.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC] send-pack.c: Allow to disable side-band-64k

2014-05-19 Thread Jonathan Nieder
Hi,

Thomas Braun wrote:

> pushing over the dump git protocol with a windows git client.

I've never heard of the dump git protocol.  Do you mean the git
protocol that's used with git:// URLs?

[...]
> Alternative approaches considered but deemed too invasive:
> - Rewrite read/write wrappers in mingw.c in order to distinguish between
>   a file descriptor which has a socket behind and a file descriptor
>   which has a file behind.

I assume here "too invasive" means "too much engineering effort"?

It sounds like a clean fix, not too invasive at all.  But I can
understand wanting a stopgap in the meantime.

> - Turning the capability side-band-64k off completely. This would remove a 
> useful
>   feature for users of non-affected transport protocols.

Would it make sense to turn off sideband unconditionally on Windows
when using the relevant protocols?

I assume someone on the list wouldn't mind writing such a patch, so I
don't think the engineering effort would be a problem for that.

Thanks,
Jonathan
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html