Re: [PATCHES] Simplify Win32 Signaling code

2005-06-05 Thread Qingqing Zhou

""Magnus Hagander"" <[EMAIL PROTECTED]> writes
>
> It *must* be done at runtime. Because you use the same binary on NT4 and
> more recent versions!
>
> Nope, we don't have any checks like that today. It's fairly trivial, but
> if examples are needed, look at pginstca.c in the pginstaller project
> where we do this.
>

Ok, understood. Shall I patch it now or after you've seen the details the
patch? And I don't have a NT on hand, so I hope I could do my best in
imagination ;-)

Regards,
Qingqing




---(end of broadcast)---
TIP 3: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-04 Thread Magnus Hagander
>> >> A quick-check (haven't checked any details) - your 
>> >unconditional use of
>> >> Global\ will not work on NT4. With 8.0 we said we wanted to 
>> >support NT4
>> >> with some limits (IIRC, tablespaces don't work, and the intaller
>> >> definitly doesn't work). If we want to continue doing 
>that (which I
>> >> think we do), the global\ has to be conditional - used on 
>2000+, not
>> >> used on <= NT4.
>> >
>> >How should he make this change?  Test OS version or use a different
>> >feature?
>> 
>> Test the OS version. The other feature that can be used is 
>named pipes,
>> and that's what we have today ;-) All other kernel objects 
>that we could
>> use all use the namespaces in the new format, but not back on NT4
>
>Do we have any place now were we test the Win32 version, that he could
>use as an example, or is this configure.in stuff?

It *must* be done at runtime. Because you use the same binary on NT4 and
more recent versions!

Nope, we don't have any checks like that today. It's fairly trivial, but
if examples are needed, look at pginstca.c in the pginstaller project
where we do this.

//Magnus

---(end of broadcast)---
TIP 6: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-04 Thread Bruce Momjian
Magnus Hagander wrote:
> >> Hi!
> >> 
> >> A quick-check (haven't checked any details) - your 
> >unconditional use of
> >> Global\ will not work on NT4. With 8.0 we said we wanted to 
> >support NT4
> >> with some limits (IIRC, tablespaces don't work, and the intaller
> >> definitly doesn't work). If we want to continue doing that (which I
> >> think we do), the global\ has to be conditional - used on 2000+, not
> >> used on <= NT4.
> >
> >How should he make this change?  Test OS version or use a different
> >feature?
> 
> Test the OS version. The other feature that can be used is named pipes,
> and that's what we have today ;-) All other kernel objects that we could
> use all use the namespaces in the new format, but not back on NT4

Do we have any place now were we test the Win32 version, that he could
use as an example, or is this configure.in stuff?

-- 
  Bruce Momjian|  http://candle.pha.pa.us
  pgman@candle.pha.pa.us   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-04 Thread Magnus Hagander
>> Hi!
>> 
>> A quick-check (haven't checked any details) - your 
>unconditional use of
>> Global\ will not work on NT4. With 8.0 we said we wanted to 
>support NT4
>> with some limits (IIRC, tablespaces don't work, and the intaller
>> definitly doesn't work). If we want to continue doing that (which I
>> think we do), the global\ has to be conditional - used on 2000+, not
>> used on <= NT4.
>
>How should he make this change?  Test OS version or use a different
>feature?

Test the OS version. The other feature that can be used is named pipes,
and that's what we have today ;-) All other kernel objects that we could
use all use the namespaces in the new format, but not back on NT4


//Magnus

---(end of broadcast)---
TIP 7: don't forget to increase your free space map settings


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-04 Thread Bruce Momjian
Magnus Hagander wrote:
> Hi!
> 
> A quick-check (haven't checked any details) - your unconditional use of
> Global\ will not work on NT4. With 8.0 we said we wanted to support NT4
> with some limits (IIRC, tablespaces don't work, and the intaller
> definitly doesn't work). If we want to continue doing that (which I
> think we do), the global\ has to be conditional - used on 2000+, not
> used on <= NT4.

How should he make this change?  Test OS version or use a different
feature?

-- 
  Bruce Momjian|  http://candle.pha.pa.us
  pgman@candle.pha.pa.us   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 7: don't forget to increase your free space map settings


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-04 Thread Magnus Hagander
Hi!

A quick-check (haven't checked any details) - your unconditional use of
Global\ will not work on NT4. With 8.0 we said we wanted to support NT4
with some limits (IIRC, tablespaces don't work, and the intaller
definitly doesn't work). If we want to continue doing that (which I
think we do), the global\ has to be conditional - used on 2000+, not
used on <= NT4.

//Magnus

>-Original Message-
>From: Qingqing Zhou [mailto:[EMAIL PROTECTED] 
>Sent: den 4 juni 2005 15:26
>To: Magnus Hagander
>Cc: pgsql-patches@postgresql.org
>Subject: Re: Simplify Win32 Signaling code
>
>
>
>Revised patch to avoid "lost signals before signaling 
>mechanism is set up
>in Win32". This was tested by plus a line:
>
>   Sleep(10*1000);
>
>in the front of pgwin32_signal_initialize().
>
>
>Regards,
>Qingqing
>

---(end of broadcast)---
TIP 8: explain analyze is your friend


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-04 Thread Qingqing Zhou

Revised patch to avoid "lost signals before signaling mechanism is set up
in Win32". This was tested by plus a line:

Sleep(10*1000);

in the front of pgwin32_signal_initialize().


Regards,
Qingqing
Index: src/port/kill.c
===
RCS file: /projects/cvsroot/pgsql/src/port/kill.c,v
retrieving revision 1.6
diff -c -r1.6 kill.c
*** src/port/kill.c 31 Dec 2004 22:03:53 -  1.6
--- src/port/kill.c 4 Jun 2005 12:16:07 -
***
*** 17,61 
  #include "c.h"
  
  #ifdef WIN32
! /* signal sending */
  int
  pgkill(int pid, int sig)
  {
!   charpipename[128];
!   BYTEsigData = sig;
!   BYTEsigRet = 0;
!   DWORD   bytes;
  
!   /* we allow signal 0 here, but it will be ignored in pg_queue_signal */
if (sig >= PG_SIGNAL_COUNT || sig < 0)
!   {
!   errno = EINVAL;
!   return -1;
!   }
if (pid <= 0)
!   {
!   /* No support for process groups */
!   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)
!   errno = ESRCH;
!   else if (GetLastError() == ERROR_ACCESS_DENIED)
!   errno = EPERM;
!   else
!   errno = EINVAL;
!   return -1;
!   }
!   if (bytes != 1 || sigRet != sig)
!   {
!   errno = ESRCH;
!   return -1;
!   }
  
!   return 0;
  }
  
  #endif
--- 17,120 
  #include "c.h"
  
  #ifdef WIN32
! 
! /* Convenience macro to set errno and return */
! #define set_error_and_return(e)   \
! do{   \
!   if (shmem)  UnmapViewOfFile(shmem); \
!   if (hShmem) CloseHandle(hShmem);\
!   if (hEvent) CloseHandle(hEvent);\
!   if (hMutex) CloseHandle(hMutex);\
!   \
!   errno = (e); \
!   return ((e) == 0)? 0 : -1;  \
! } while (0)
! 
! /* 
!  * pgkill
!  *kill() win32 emulation. 
!  *
!  *pgkill() will fail if: 
!  *[EINVAL] The value of the sig argument is an invalid 
!  * or target process id <= 0.
!  *[ESRCH]  No process can be found corresponding to that 
!  * specified by pid.  
!  *[EPERM]  Any other win32 system call fails.
!  */
  int
  pgkill(int pid, int sig)
  {
!   charname[64];
!   HANDLE  hShmem, hMutex, hEvent;
!   Win32SignalShmemStruct *shmem;
! 
!   shmem  = NULL;
!   hShmem = NULL;
!   hMutex = NULL;
!   hEvent = NULL;
  
!   /* we allow signal 0 here, and handle later */
if (sig >= PG_SIGNAL_COUNT || sig < 0)
!   set_error_and_return(EINVAL);
!   
!   /* No support for process groups */
if (pid <= 0)
!   set_error_and_return(EINVAL);
!   
!   /* 
!* Attach to the signaling shared memory. If it is attachable,
!* we decide that the process is alive. 
!*/
!   wsprintf(name, "%s.%d", SIGNAL_SHMEM_PREFIX, pid);
!   if (NULL == (hShmem = OpenFileMapping(FILE_MAP_ALL_ACCESS, 
!   FALSE, 
!   name)))
!   set_error_and_return(ESRCH);
!   
!   if (sig == 0)
!   set_error_and_return(0);
! 
!   if (NULL == (shmem = MapViewOfFile(hShmem, 
!   FILE_MAP_ALL_ACCESS,   
!   0, 0, 0)))
!   set_error_and_return(EPERM);
! 
!   /* Grab the mutex */
!   wsprintf(name, "%s.%d", SIGNAL_MUTEX_PREFIX, pid);
!   if (NULL == (hMutex = OpenMutex(MUTEX_ALL_ACCESS, 
!   FALSE, name)))
!   set_error_and_return(EPERM);
! 
!   if (WaitForSingleObject(hMutex, INFINITE) != WAIT_OBJECT_0) 
!   set_error_and_return(EPERM);
! 
!   /* Write down the signal number */
!   shmem->queue |= sigmask(sig);
!   
!   /* 
!* If we can't release the mutex, we have to exit the
!* process to make mutex released by the system. If we 
!* can't set the event, that's really awkward, but the 
!* target process would find out the signal when next
!* set event is successfully done. 
!*/
!   if (!ReleaseMutex(hMutex))
!   set_error_and_return(EPERM);
! 
!   if (!UnmapViewOfFile(shmem))
!   set_error_and_return(EPERM);
! 
!   /* Set event */
!   wsprintf(name, "%s.%d", SIGNAL_EVENT_PREFIX, pid);
!   if

Re: [PATCHES] Simplify Win32 Signaling code

2005-06-02 Thread Qingqing Zhou

In thread:
http://archives.postgresql.org/pgsql-hackers-win32/2004-11/msg00010.php
---
>Do we actually need to pass the handle, or could the subprocess reopen
>the pipe for itself?

Nope, we need to pass the handle. Only one process can be the
server-side of the pipe, and once the postmaster has opened it, the
child process can't do it - the only way to get it is through
inheritance.
---

In current implementation, we can reopen it, but the problem is that when
postmaster should close those three (shmem, mutex, event) handles? So the
best way is still "Postmaster create them, duplicate these handles in
BackendParameters and the child inheritates them". Do I got your meaning?

Regards,
Qingqing



---(end of broadcast)---
TIP 6: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-02 Thread Qingqing Zhou

""Magnus Hagander"" <[EMAIL PROTECTED]> writes
>
> Looking at this patch reminds me of another discussion we had:
>
> Signals sent by the postmaster *before the signaling code is running in
> the child* has to be handled.
>
> This is handled in the curernt code by creating the pipe in the
> postmaster and then inheriting it. You'll need something similar in this
> one - create the stuff in the postmaster and inherit it down. (this is
> the initial_signal_pipe and pgwin32_create_signal_listener(), which you
> removed)
>
> Sorry, forgot to bring this up earlier because I had completely forgot
> it. You'll find some details if you search the archives, I beleive.
>

Is this thread:
http://archives.postgresql.org/pgsql-hackers-win32/2004-11/msg0.php

It is my fault to ignore this - I just *simply* removed those lines ... I
will look into the problem and come up with a patch.

Regards,
Qingqing




---(end of broadcast)---
TIP 9: the planner will ignore your desire to choose an index scan if your
  joining column's datatypes do not match


Re: [PATCHES] Simplify Win32 Signaling code

2005-06-02 Thread Magnus Hagander
> This patch simplified Win32 signaling code per discussion in 
> hackers. In this implementation, each process will have a 
> named (by its pid) mutex, named shared memory area and named 
> event in global namespace. The process is sending/receiving 
> signals as the following:
> 
> (*) the process who kill the signal:
>  - Grab the named mutex, set signal bit in target process's 
> shared memory area and SetEvent(), then it is done;
> 
> (*) the process who should receive the signal:
>  - the main thread of this process could be awakened by the 
> event from waiting status(like semop()) or 
> CHECK_FOR_INTERRUPTS() actively; -- there is no other threads 
> of the process;
> 
> Details could be found in this thread and follows:
> http://archives.postgresql.org/pgsql-hackers/2005-05/msg01388.php

Looking at this patch reminds me of another discussion we had:

Signals sent by the postmaster *before the signaling code is running in
the child* has to be handled.

This is handled in the curernt code by creating the pipe in the
postmaster and then inheriting it. You'll need something similar in this
one - create the stuff in the postmaster and inherit it down. (this is
the initial_signal_pipe and pgwin32_create_signal_listener(), which you
removed)

Sorry, forgot to bring this up earlier because I had completely forgot
it. You'll find some details if you search the archives, I beleive.

//Magnus

---(end of broadcast)---
TIP 6: Have you searched our list archives?

   http://archives.postgresql.org


[PATCHES] Simplify Win32 Signaling code

2005-06-02 Thread Qingqing Zhou

This patch simplified Win32 signaling code per discussion in hackers. In
this implementation, each process will have a named (by its pid) mutex,
named shared memory area and named event in global namespace. The process
is
sending/receiving signals as the following:

(*) the process who kill the signal:
 - Grab the named mutex, set signal bit in target process's shared memory
area and SetEvent(), then it is done;

(*) the process who should receive the signal:
 - the main thread of this process could be awakened by the event from
waiting status(like semop()) or CHECK_FOR_INTERRUPTS() actively; -- there
is
no other threads of the process;

Details could be found in this thread and follows:
http://archives.postgresql.org/pgsql-hackers/2005-05/msg01388.php


Regards,
Qingqing
Index: backend/port/win32/signal.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/port/win32/signal.c,v
retrieving revision 1.11
diff -c -r1.11 signal.c
*** backend/port/win32/signal.c 31 Dec 2004 22:00:37 -  1.11
--- backend/port/win32/signal.c 2 Jun 2005 12:38:32 -
***
*** 14,43 
  #include "postgres.h"
  
  #include 
  
  
! /* pg_signal_crit_sec is used to protect only pg_signal_queue. That is the 
only
!  * variable that can be accessed from the signal sending threads! */
! static CRITICAL_SECTION pg_signal_crit_sec;
! static intpg_signal_queue;
  
  static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT];
  static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];
  static intpg_signal_mask;
  
- DLLIMPORT HANDLE pgwin32_signal_event;
- HANDLE pgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
- 
- 
- /* Signal handling thread function */
- static DWORD WINAPI pg_signal_thread(LPVOID param);
  static BOOL WINAPI pg_console_handler(DWORD dwCtrlType);
  
! /* Sleep function that can be interrupted by signals */
  void
  pgwin32_backend_usleep(long microsec)
  {
!   if (WaitForSingleObject(pgwin32_signal_event, (microsec < 500 ? 1 : 
(microsec + 500) / 1000)) == WAIT_OBJECT_0)
{
pgwin32_dispatch_queued_signals();
errno = EINTR;
--- 14,57 
  #include "postgres.h"
  
  #include 
+ #include "miscadmin.h"
  
+ /* Simplified ereport for this module */
+ #define ereport_signal(elevel, msg)   \
+   ereport((elevel), \
+   (errmsg_internal("%s: error code: %d", (msg), 
(int)GetLastError(;
+ 
+ /* Lock/Unlock signal area primitives */
+ #define lock_signal_shmem()   \
+ do { \
+   if (WaitForSingleObject(MySignalShmem->mutex, INFINITE) != 
WAIT_OBJECT_0)   \
+   ereport_signal(ERROR, "failed to wait on signal mutex");
\
+ }while(0)
+ 
+ #define unlock_signal_shmem() \
+ do{   \
+   if (!ReleaseMutex(MySignalShmem->mutex))\
+   ereport_signal(ERROR, "failed to release signal mutex");
\
+ }while(0)
  
! /* Point to signal shared memory of current process */
! DLLIMPORT Win32SignalShmemStruct  *MySignalShmem;
  
  static pqsigfunc pg_signal_array[PG_SIGNAL_COUNT];
  static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT];
  static intpg_signal_mask;
  
  static BOOL WINAPI pg_console_handler(DWORD dwCtrlType);
  
! /* 
!  * pgwin32_backend_usleep
!  *Sleep function that can be interrupted by signals 
!  */
  void
  pgwin32_backend_usleep(long microsec)
  {
!   if (WaitForSingleObject(pgwin32_signal_event, (microsec < 500 ? 
!   1 : 
(microsec + 500) / 1000)) == WAIT_OBJECT_0)
{
pgwin32_dispatch_queued_signals();
errno = EINTR;
***
*** 45,101 
}
  }
  
! 
! /* Initialization */
  void
  pgwin32_signal_initialize(void)
  {
int i;
!   HANDLE  signal_thread_handle;
! 
!   InitializeCriticalSection(&pg_signal_crit_sec);
  
for (i = 0; i < PG_SIGNAL_COUNT; i++)
{
pg_signal_array[i] = SIG_DFL;
pg_signal_defaults[i] = SIG_IGN;
}
pg_signal_mask = 0;
-   pg_signal_queue = 0;
  
!   /* Create the global event handle used to flag signals */
!   pgwin32_signal_event = CreateEvent(NULL, TRUE, FALSE, NULL);
!   if (pgwin32_signal_event == NULL)
!   ereport(FATAL,
!   (errmsg_internal("failed to create signal 
event: %d", (int) GetLastError(;
! 
!   /* Create thread for handling signals */
!   signal_thread_handle = CreateThread(NULL, 0, pg_signal_thread, NULL, 0, 
NULL);
!   if (signal_thread_handle == NULL)
!   ereport(FATAL,
!   (errmsg_internal("failed to create signal handler 
thread")));
  
/* Create console control handle to pick up Ctrl-C etc */
if (!SetConsoleCtrlHandler(pg_console_handler, TRUE))
!   ereport(FATAL,
!(