[gs-cvs] gs/src

Russell Lang ghostgum at ghostscript.com
Wed Jul 7 02:20:59 PDT 2004


Update of /cvs/ghostscript/gs/src
In directory casper:/tmp/cvs-serv23765/src

Modified Files:
      Tag: GS_8_1X
	gp_msprn.c 
Log Message:
In the Windows %printer% IODevice, the existing thread handle
is closed automatically when the thread finishes.  Duplicate
the thread handle so we always have a valid handle for waiting
and closing.

DETAILS:
When the thread finishes, the CRTL _endthread is closing
the existing handle.  During debugging, it was found that
waiting on the thread handle was Ok because the thread 
was still running, but by the time CloseHandle ran the
thread handle was invalid.

IODevices are effectively static, so iodev->state is initialized
once at the start of the interpreter.  There is no need to
test if iodev->state is valid.


Index: gp_msprn.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gp_msprn.c,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -d -r1.3 -r1.3.2.1
--- gp_msprn.c	21 Feb 2002 22:24:52 -0000	1.3
+++ gp_msprn.c	7 Jul 2004 09:20:57 -0000	1.3.2.1
@@ -151,6 +151,7 @@
     HANDLE hprinter;
     int pipeh[2];
     unsigned long tid;
+    HANDLE hthread;
     char pname[gp_file_name_sizeof];
     unsigned long *ptid = &((tid_t *)(iodev->state))->tid;
 
@@ -164,9 +165,6 @@
 	return_error(gs_error_invalidfileaccess);
     ClosePrinter(hprinter);
 
-    if (iodev->state == NULL)
-	return_error(gs_error_invalidfileaccess);
-
     /* Create a pipe to connect a FILE pointer to a Windows printer. */
     if (_pipe(pipeh, 4096, _O_BINARY) != 0)
 	return_error(gs_fopen_errno_to_code(errno));
@@ -179,12 +177,23 @@
     }
 
     /* start a thread to read the pipe */
-    *ptid = _beginthread(&mswin_printer_thread, 32768, pipeh[0]);
-    if (*ptid == -1) {
+    tid = _beginthread(&mswin_printer_thread, 32768, pipeh[0]);
+    if (tid == -1) {
 	fclose(*pfile);
 	close(pipeh[0]);
 	return_error(gs_error_invalidfileaccess);
     }
+    /* Duplicate thread handle so we can wait on it
+     * even if original handle is closed by CRTL
+     * when the thread finishes.
+     */
+    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)tid,
+	GetCurrentProcess(), &hthread, 
+	0, FALSE, DUPLICATE_SAME_ACCESS)) {
+	fclose(*pfile);
+	return_error(gs_error_invalidfileaccess);
+    }
+    *ptid = (unsigned long)hthread;
 
     /* Give the name of the printer to the thread by writing
      * it to the pipe.  This is avoids elaborate thread 
@@ -202,7 +211,7 @@
     unsigned long *ptid = &((tid_t *)(iodev->state))->tid;
     HANDLE hthread;
     fclose(file);
-    if ((iodev->state != NULL) && (*ptid != -1)) {
+    if (*ptid != -1) {
 	/* Wait until the print thread finishes before continuing */
 	hthread = (HANDLE)*ptid;
 	WaitForSingleObject(hthread, 60000);



More information about the gs-cvs mailing list