A discussion on -general has been ongoing in which is was discovered that 8.3 can exhaust the desktop heap allocated to a service with ~45 connections at which point the server will crash.
Desktop heap is allocated by user32.dll and shell32 on a per-process basis from a 512KB pool for a non-interactive logon (on XP) and 3072KB pool for an interactive logon. The attached patch removes our direct dependencies on these DLLs, reducing the overhead from around 9.7KB per backend to around 3.5KB. This is back in the range we had with 8.2. Unfortunately, there are still indirect dependencies on user32.dll which I don't think we'll be able to do anything about. If desktop heap is still exhausted with larger installations, the allocated heap size can be increased in the registry. See http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx for more info. Regards, Dave
Index: src/backend/port/win32/signal.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/port/win32/signal.c,v retrieving revision 1.18 diff -c -r1.18 signal.c *** src/backend/port/win32/signal.c 5 Jan 2007 22:19:35 -0000 1.18 --- src/backend/port/win32/signal.c 23 Oct 2007 14:44:35 -0000 *************** *** 178,184 **** char pipename[128]; HANDLE pipe; ! wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%d", (int) pid); pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, --- 178,184 ---- char pipename[128]; HANDLE pipe; ! snprintf(pipename, sizeof(pipename) - 1, "\\\\.\\pipe\\pgsignal_%u", (int) pid); pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, *************** *** 251,257 **** char pipename[128]; HANDLE pipe = pgwin32_initial_signal_pipe; ! wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%d", GetCurrentProcessId()); for (;;) { --- 251,257 ---- char pipename[128]; HANDLE pipe = pgwin32_initial_signal_pipe; ! snprintf(pipename, sizeof(pipename) - 1, "\\\\.\\pipe\\pgsignal_%u", GetCurrentProcessId()); for (;;) { Index: src/port/kill.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/port/kill.c,v retrieving revision 1.8 diff -c -r1.8 kill.c *** src/port/kill.c 5 Jan 2007 22:20:02 -0000 1.8 --- src/port/kill.c 23 Oct 2007 14:44:35 -0000 *************** *** 38,44 **** errno = EINVAL; return -1; } ! wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%i", pid); if (!CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000)) { if (GetLastError() == ERROR_FILE_NOT_FOUND) --- 38,44 ---- errno = EINVAL; return -1; } ! snprintf(pipename, sizeof(pipename) - 1, "\\\\.\\pipe\\pgsignal_%u", pid); if (!CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000)) { if (GetLastError() == ERROR_FILE_NOT_FOUND) Index: src/port/path.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/port/path.c,v retrieving revision 1.71 diff -c -r1.71 path.c *** src/port/path.c 5 Jan 2007 22:20:02 -0000 1.71 --- src/port/path.c 23 Oct 2007 14:47:29 -0000 *************** *** 628,637 **** strlcpy(ret_path, pwd->pw_dir, MAXPGPATH); return true; #else ! char tmppath[MAX_PATH]; ZeroMemory(tmppath, sizeof(tmppath)); ! if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK) return false; snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath); return true; --- 628,643 ---- strlcpy(ret_path, pwd->pw_dir, MAXPGPATH); return true; #else ! char *tmppath=0; ZeroMemory(tmppath, sizeof(tmppath)); ! ! /* ! * Note: We use getenv here because the more modern SHGetSpecialFolderPath() ! * will force us to link with shell32.lib which eats valuable desktop heap. ! */ ! tmppath = getenv("APPDATA"); ! if (!tmppath) return false; snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath); return true;
---------------------------(end of broadcast)--------------------------- TIP 3: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq