On Mon, May 14, 2007 at 09:34:05AM -0400, Andrew Dunstan wrote: > > > Magnus Hagander wrote: > >On Mon, May 14, 2007 at 09:02:10AM -0400, Tom Lane wrote: > > > >>Magnus Hagander <[EMAIL PROTECTED]> writes: > >> > >>>If all we want to do is add a check that prevents two servers to start on > >>>the same port, we could do that trivially in a win32 specific way (since > >>>we'll never have unix sockets there). Just create an object in the global > >>>namespace named postgresql.interlock.<portnumber> or such a thing. > >>> > >>Does it go away automatically on postmaster crash? > >> > > > >Yes. > > > > > > > > Then I think it's worth adding, and I'd argue that as a low risk safety > measure we should allow it to sneak into 8.3. I'm assuming the code > involved will be quite small.
Yes, see attached. BTW, did you mean 8.2? One typical case where this could happen is in an upgrade scenario, I think... //Magnus
Index: src/backend/libpq/pqcomm.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/libpq/pqcomm.c,v retrieving revision 1.191 diff -c -r1.191 pqcomm.c *** src/backend/libpq/pqcomm.c 3 Mar 2007 19:32:54 -0000 1.191 --- src/backend/libpq/pqcomm.c 14 May 2007 13:52:05 -0000 *************** *** 261,266 **** --- 261,291 ---- snprintf(portNumberStr, sizeof(portNumberStr), "%d", portNumber); service = portNumberStr; } + #ifdef WIN32 + /* Win32 doesn't have Unix sockets, but will allow multiple processes + * to listen on the same port. This interlock is to prevent that. + */ + { + char mutexName[64]; + HANDLE mutex; + + sprintf(mutexName,"postgresql.interlock.%i", portNumber); + mutex = CreateMutex(NULL, FALSE, mutexName); + if (mutex == NULL) + ereport(FATAL, + (errmsg_internal("could not create interlocking mutex: %li", + GetLastError()))); + + if (GetLastError() == ERROR_ALREADY_EXISTS) + ereport(FATAL, + (errcode(ERRCODE_LOCK_FILE_EXISTS), + errmsg("interlock mutex \"%s\" already exists", mutexName), + errhint("Is another postgres listening on port %i", portNumber))); + + /* Intentionally leak the handle until process exit, so the mutex + * isn't freed. It will be automatically freed when the process exits. */ + } + #endif ret = pg_getaddrinfo_all(hostName, service, &hint, &addrs); if (ret || !addrs)
---------------------------(end of broadcast)--------------------------- TIP 6: explain analyze is your friend