From: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
To: Alexandr Miloslavskiy via GitGitGadget <gitgitgadget@gmail.com>,
git@vger.kernel.org
Cc: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>,
Erik Faye-Lund <kusmabite@gmail.com>
Subject: Test program used to prove quota's behavior
Date: Thu, 13 Feb 2020 19:41:47 +0100 [thread overview]
Message-ID: <86c3fad5-4fa7-7bb0-37cc-7c43e6f2eedc@syntevo.com> (raw)
In-Reply-To: <pull.553.git.1581619239467.gitgitgadget@gmail.com>
///////////////////////////////////////////////////////////////////////////////
// NTDLL declarations
typedef struct _FILE_PIPE_LOCAL_INFORMATION {
ULONG NamedPipeType;
ULONG NamedPipeConfiguration;
ULONG MaximumInstances;
ULONG CurrentInstances;
ULONG InboundQuota;
ULONG ReadDataAvailable;
ULONG OutboundQuota;
ULONG WriteQuotaAvailable;
ULONG NamedPipeState;
ULONG NamedPipeEnd;
} FILE_PIPE_LOCAL_INFORMATION, * PFILE_PIPE_LOCAL_INFORMATION;
typedef struct _IO_STATUS_BLOCK
{
union {
DWORD Status;
PVOID Pointer;
} u;
ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef enum _FILE_INFORMATION_CLASS {
FilePipeLocalInformation = 24
} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS;
typedef DWORD (WINAPI* PNtQueryInformationFile)(HANDLE,
IO_STATUS_BLOCK*, VOID*, ULONG, FILE_INFORMATION_CLASS);
///////////////////////////////////////////////////////////////////////////////
ULONG GetPipeAvailWriteBuffer(HANDLE a_PipeHandle)
{
static PNtQueryInformationFile NtQueryInformationFile =
(PNtQueryInformationFile)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),
"NtQueryInformationFile");
IO_STATUS_BLOCK statusBlock = {};
FILE_PIPE_LOCAL_INFORMATION pipeInformation = {};
if (0 != NtQueryInformationFile(a_PipeHandle, &statusBlock,
&pipeInformation, sizeof(pipeInformation), FilePipeLocalInformation))
assert(0);
return pipeInformation.WriteQuotaAvailable;
}
void ReadPipe(HANDLE a_Pipe, DWORD a_Size)
{
void* buffer = malloc(a_Size);
DWORD bytesDone = 0;
assert(ReadFile(a_Pipe, buffer, a_Size, &bytesDone, NULL));
assert(bytesDone == a_Size);
free(buffer);
}
void WritePipe(HANDLE a_Pipe, DWORD a_Size)
{
void* buffer = malloc(a_Size);
DWORD bytesDone = 0;
assert(WriteFile(a_Pipe, buffer, a_Size, &bytesDone, NULL));
assert(bytesDone == a_Size);
free(buffer);
}
struct ThreadReadParam
{
HANDLE Pipe;
DWORD Size;
};
DWORD WINAPI ThreadReadPipe(void* a_Param)
{
const ThreadReadParam* param = (const ThreadReadParam*)a_Param;
ReadPipe(param->Pipe, param->Size);
return 0;
}
void Test()
{
HANDLE readPipe = 0;
HANDLE writePipe = 0;
const DWORD pipeBufferSize = 0x8000;
assert(CreatePipe(&readPipe, &writePipe, NULL, pipeBufferSize));
DWORD expectedBufferSize = pipeBufferSize;
assert(expectedBufferSize == GetPipeAvailWriteBuffer(writePipe));
// Test 1: nothing unexpected here.
// Write some data to pipe, occupying portion of write buffer.
{
const DWORD size = 0x1000;
WritePipe(writePipe, size);
expectedBufferSize -= size;
assert(expectedBufferSize == GetPipeAvailWriteBuffer(writePipe));
}
// Test 2: nothing unexpected here.
// Read some of written data, releasing portion of write buffer.
{
const DWORD size = 0x0800;
ReadPipe(readPipe, size);
expectedBufferSize += size;
assert(expectedBufferSize == GetPipeAvailWriteBuffer(writePipe));
}
// Test 3: nothing unexpected here.
// Read remaining written data, releasing entire buffer.
{
const DWORD size = 0x0800;
ReadPipe(readPipe, size);
expectedBufferSize += size;
assert(expectedBufferSize == GetPipeAvailWriteBuffer(writePipe));
}
// Test 4: that's the unexpected part.
// Start reading the empty pipe and this reduces the *write* buffer.
{
ThreadReadParam param;
param.Pipe = readPipe;
param.Size = 0x8000;
HANDLE thread = CreateThread(NULL, 0, ThreadReadPipe, ¶m, 0, NULL);
Sleep(1000);
expectedBufferSize -= param.Size;
assert(expectedBufferSize == GetPipeAvailWriteBuffer(writePipe));
// Write pipe to release thread
WritePipe(writePipe, param.Size);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
expectedBufferSize += param.Size;
assert(expectedBufferSize == GetPipeAvailWriteBuffer(writePipe));
}
CloseHandle(writePipe);
CloseHandle(readPipe);
}
next prev parent reply other threads:[~2020-02-13 18:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-13 18:40 [PATCH] mingw: workaround for hangs when sending STDIN Alexandr Miloslavskiy via GitGitGadget
2020-02-13 18:41 ` Alexandr Miloslavskiy [this message]
2020-02-13 18:56 ` Eric Sunshine
2020-02-13 19:22 ` Alexandr Miloslavskiy
2020-02-17 16:25 ` [PATCH v2] " Alexandr Miloslavskiy via GitGitGadget
2020-02-17 17:24 ` Eric Sunshine
2020-02-17 17:56 ` Junio C Hamano
2020-02-17 18:01 ` Alexandr Miloslavskiy
2020-02-17 18:01 ` [PATCH v3] " Alexandr Miloslavskiy via GitGitGadget
2020-02-18 16:39 ` Junio C Hamano
2020-02-27 21:15 ` Johannes Schindelin
2020-02-27 22:59 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=86c3fad5-4fa7-7bb0-37cc-7c43e6f2eedc@syntevo.com \
--to=alexandr.miloslavskiy@syntevo.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=kusmabite@gmail.com \
--cc=ungureanupaulsebastian@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).