in reply to Re^2: Read STDOUT from Win32::Job while process is running in thread Read STDOUT from Win32::Job while process is running
warning: extra args ignored after '-e'
This warning doesn't ring any bells with me. How did you install Inline ? (You need to build and install it from source - eg doing a 'ppm install' won't do.) Knowing the output of 'perl -V' would also help - as, too, would knowing any additional diagnostics that you're getting. The code, as posted by BrowserUk, won't compile for me using the MinGW port of gcc-3.4.5, because of a deficiency in winnt.h. In that file you'll need to add:
#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x2000
For some reason (that I haven't yet investigated), with ActivePerl I then get undefined references to `CreateJobObjectA', `SetInformationJobObject', `AssignProcessToJobObject' - which is odd, because these symbols are all defined in libbkernel32.a and we link to that library. (It may just be that we need to link to libkernel32.a *before* JobObject.o.) Anyway, if you get to the same snag we can dig a bit deeper then. First we need to work out what that warning is all about. Cheers, Rob
Re^4: Read STDOUT from Win32::Job while process is running
by syphilis (Archbishop) on Mar 11, 2012 at 08:36 UTC
|
For some reason (that I haven't yet investigated), with ActivePerl I then get undefined references to `CreateJobObjectA', `SetInformationJobObject', `AssignProcessToJobObject'
Well ... I investigated and investigated ... then investigated a bit more ... and still couldn't see what the problem was. So I then gave up and posted to the ActiveState users list - and about half an hour later Mark Dootson replied with the explanation and solution.
When this linking problem occurs, we'll find that lib/CORE/win32.h begins with something like:
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
#endif
But we need _WIN32_WINNT to be >= 0x0500 - which I achieved by altering the above code to:
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0500
#endif
That then enables the script to run to completion, and I think it also takes care of the '...undefined; assuming extern returning int' warnings with Microsoft compilers.
Cheers, Rob
| [reply] [d/l] [select] |
|
Wow, thank you so much for taking time to investigate and even writing to ActiveState. It's working now and I'm happy.
Here the successful output:
E:\perl\Win32-JobAdd-0.01>dmake
cp lib/Win32/JobAdd.pm blib\lib\Win32\JobAdd.pm
C:\Perl\bin\perl.exe C:\Perl\lib\ExtUtils\xsubpp -typemap C:\Perl\lib
+\ExtUtils\
typemap JobAdd.xs > JobAdd.xsc && C:\Perl\bin\perl.exe -MExtUtils::Co
+mmand -e "
mv" -- JobAdd.xsc JobAdd.c
Please specify prototyping behavior for JobAdd.xs (see perlxs manual)
C:/Perl/site/bin/gcc.exe -c -I. -DNDEBUG -DWIN32 -D_CONSOLE -D
+NO_STRICT
-DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMP
+LICIT_CONT
EXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -DHASATTRIB
+UTE -fno-s
trict-aliasing -mms-bitfields -O2 -DVERSION=\"0.01\" -DXS_V
+ERSION=\"0
.01\" "-IC:\Perl\lib\CORE" JobAdd.c
JobAdd.xs: In function `createJobObject':
JobAdd.xs:18: warning: passing arg 1 of `SetInformationJobObject' make
+s pointer
from integer without a cast
JobAdd.xs: In function `assignProcessToJobObject':
JobAdd.xs:24: warning: passing arg 1 of `AssignProcessToJobObject' mak
+es pointer
from integer without a cast
Running Mkbootstrap for Win32::JobAdd ()
C:\Perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 JobAdd.bs
C:\Perl\bin\perl.exe -MExtUtils::Mksymlists \
-e "Mksymlists('NAME'=>\"Win32::JobAdd\", 'DLBASE' => 'JobAdd', '
+DL_FUNCS'
=> { }, 'FUNCLIST' => [], 'IMPORTS' => { }, 'DL_VARS' => []);"
Set up gcc environment - 3.4.5 (mingw-vista special r3)
dlltool --def JobAdd.def --output-exp dll.exp
C:\Perl\site\bin\g++.exe -o blib\arch\auto\Win32\JobAdd\JobAdd.dll -Wl
+,--base-fi
le -Wl,dll.base -mdll -L"C:\Perl\lib\CORE" JobAdd.o -Wl,--image-base,0
+x2e0b0000
C:\Perl\lib\CORE\perl510.lib -lkernel32 -luser32 -lgdi32 -lwinspool -
+lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lm
+pr -lwinmm
-lversion -lodbc32 -lodbccp32 -lcomctl32 -lmsvcrt dll.exp
dlltool --def JobAdd.def --base-file dll.base --output-exp dll.exp
C:\Perl\site\bin\g++.exe -o blib\arch\auto\Win32\JobAdd\JobAdd.dll -md
+ll -L"C:\P
erl\lib\CORE" JobAdd.o -Wl,--image-base,0x2e0b0000 C:\Perl\lib\CORE\p
+erl510.lib
-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell3
+2 -lole32
-loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32
+ -lodbccp3
2 -lcomctl32 -lmsvcrt dll.exp
C:\Perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 755 blib\arch\a
+uto\Win32\
JobAdd\JobAdd.dll
C:\Perl\bin\perl.exe -MExtUtils::Command -e "cp" -- JobAdd.bs blib\arc
+h\auto\Win
32\JobAdd\JobAdd.bs
C:\Perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 blib\arch\a
+uto\Win32\
JobAdd\JobAdd.bs
| [reply] [d/l] |
|
Well ... I investigated and investigated ... then investigated a bit more ... and still couldn't see what the problem was.
So I then gave up and posted to the ActiveState users list - and about half an hour later Mark Dootson replied with the explanation and solution.
Well done and thank you.++
Rather than requiring the Perl sources modification -- which might be needed by something somewhere -- adding the define before the inclusion of the Perl headers achieves the same thing in a self-contained way. I've also cleaned up a couple of the warnings -- though traded them for others in some cases, but I'm not sure there is a better way?
The result looks like this:
#define _WIN32_WINNT 0x0500
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x2000
#endif
int createJobObject( char *name ) {
HANDLE job;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0, };
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_J
+OB_CLOSE;
job = CreateJobObjectA( NULL, name );
SetInformationJobObject( job, 9, &jeli, sizeof(jeli) );
return (int)job;
}
int assignProcessToJobObject( int job, int pid ) {
HANDLE hProc = OpenProcess( PROCESS_SET_QUOTA |PROCESS_TERMINATE,
+0, pid );
return (int)AssignProcessToJobObject( (HANDLE)job, hProc );
}
int closeHandle( int handle ) {
return (int)CloseHandle( (HANDLE)handle );
}
MODULE = Win32::JobAdd PACKAGE = Win32::JobAdd
int
createJobObject (name)
char * name
int
assignProcessToJobObject (job, pid)
int job
int pid
int
closeHandle (handle)
int handle
Salient part of the build trace: JobAdd.c
JobAdd.xs(18) : warning C4311: 'type cast' : pointer truncation from '
+HANDLE' to 'int'
JobAdd.xs(24) : warning C4312: 'type cast' : conversion from 'int' to
+'HANDLE' of greater size
JobAdd.xs(28) : warning C4312: 'type cast' : conversion from 'int' to
+'HANDLE' of greater size
link -out:blib\arch\auto\Win32\JobAdd\JobAdd.dll -dll -nologo
+-nodefaultlib -debug -opt:ref,icf -ltcg ...
Creating library blib\arch\auto\Win32\JobAdd\JobAdd.lib and object
+blib\arch\auto\Win32\JobAdd\JobAdd.exp
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
| [reply] [d/l] [select] |
|
adding the define before the inclusion of the Perl headers achieves the same thing in a self-contained way
Yes - I was looking at the Inline::C approach which, afaik, doesn't provide that option - it always inserts the inclusion of perl.h and friends *before* any C code that the author of the script provides.
Hmm ... maybe Inline::C should provide an option that allows one to place C code ahead of those inclusions. (TODO ?)
In this particular instance I think that modifying CORE/win32.h should be safe (no guarantees, but :-) - so long as you're running on XP or higher. After all, if CORE/win32.h did its job properly I think it would assign the actual value associated with the OS on which perl was running, not just provide a minimum supported value.
Cheers, Rob
| [reply] |
|
|
|
|
#!/usr/bin/perl
use strict;
use threads;
use Thread::Queue;
use Win32::JobAdd;
## A shared var to communicate progess between work thread and TK
my $Q = new Thread::Queue;
my $job:shared = createJobObject( 'counter_and_calc_job' );
sub work{
my $pid = open PROC,
q[perl -le "$|=1; system 1, 'calc.exe'; print and select(undef,und
+ef,undef,0.1) for 1 .. 1000" |]
or die $!;
assignProcessToJobObject( $job, $pid );
while( <PROC> ) {
$Q->enqueue( $_ );
}
close PROC;
}
threads->new( \&work )->detach;
## For lowest memory consumption require (not use)
## Tk::* after you've started the work thread.
require Tk::ProgressBar;
my $mw = MainWindow->new;
my $pb = $mw->ProgressBar()->pack();
my $button = $mw->Button(-text => 'CANCEL',
-command => sub { closeHandle( $job ) } )->pa
+ck();
my $repeat;
$repeat = $mw->repeat( 100 => sub {
while( $Q->pending ) {
my $progress = $Q->dequeue;
return unless $progress;
$repeat->cancel if $progress == 100;
$pb->value( $progress )
}
});
$mw->MainLoop;
This code solves my two problems. Being able to read from a child process, but also being able to kill the whole process tree instead of only killing the child process and to have zombie processes.
If you press the "Cancel" Button then the calculator and the child process which counts from 1 to 1000 are killed. Even if you quit the gui with the cross in the right upper corner the grandchild process "calculator" is killed.
Without a job environment in a Win32 environment the grandchild calculator would stay as a zombie process.
Feedback to this code is welcome.
Cheers, Dirk | [reply] [d/l] |
Re^4: Read STDOUT from Win32::Job while process is running
by Dirk80 (Pilgrim) on Mar 11, 2012 at 08:37 UTC
|
Thanks alot for your answer. I installed it via "ppm". I'll install it via cpan to avoid the warning.
Now BrowserUk developed a Win32-JobAdd package which contains the same C code in a xs file. And you're right I had to set the value 0x2000 for the constant. And now I get exactly the undefined references which you describe.
Here the messages:
E:\perl\Win32-JobAdd-0.01>dmake
cp lib/Win32/JobAdd.pm blib\lib\Win32\JobAdd.pm
C:\Perl\bin\perl.exe C:\Perl\lib\ExtUtils\xsubpp -typemap C:\Perl\lib
+\ExtUtils\
typemap JobAdd.xs > JobAdd.xsc && C:\Perl\bin\perl.exe -MExtUtils::Co
+mmand -e "
mv" -- JobAdd.xsc JobAdd.c
Please specify prototyping behavior for JobAdd.xs (see perlxs manual)
C:/Perl/site/bin/gcc.exe -c -I. -DNDEBUG -DWIN32 -D_CONSOLE -D
+NO_STRICT
-DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMP
+LICIT_CONT
EXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -DHASATTRIB
+UTE -fno-s
trict-aliasing -mms-bitfields -O2 -DVERSION=\"0.01\" -DXS_V
+ERSION=\"0
.01\" "-IC:\Perl\lib\CORE" JobAdd.c
Running Mkbootstrap for Win32::JobAdd ()
C:\Perl\bin\perl.exe -MExtUtils::Command -e "chmod" -- 644 JobAdd.bs
C:\Perl\bin\perl.exe -MExtUtils::Mksymlists \
-e "Mksymlists('NAME'=>\"Win32::JobAdd\", 'DLBASE' => 'JobAdd', '
+DL_FUNCS'
=> { }, 'FUNCLIST' => [], 'IMPORTS' => { }, 'DL_VARS' => []);"
Set up gcc environment - 3.4.5 (mingw-vista special r3)
dlltool --def JobAdd.def --output-exp dll.exp
C:\Perl\site\bin\g++.exe -o blib\arch\auto\Win32\JobAdd\JobAdd.dll -Wl
+,--base-fi
le -Wl,dll.base -mdll -L"C:\Perl\lib\CORE" JobAdd.o -Wl,--image-base,0
+x2e0b0000
C:\Perl\lib\CORE\perl510.lib -lkernel32 -luser32 -lgdi32 -lwinspool -
+lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lm
+pr -lwinmm
-lversion -lodbc32 -lodbccp32 -lcomctl32 -lmsvcrt dll.exp
JobAdd.o:JobAdd.c:(.text+0x3f): undefined reference to `CreateJobObjec
+tA'
JobAdd.o:JobAdd.c:(.text+0x5f): undefined reference to `SetInformation
+JobObject'
JobAdd.o:JobAdd.c:(.text+0xa1): undefined reference to `AssignProcessT
+oJobObject
'
collect2: ld returned 1 exit status
dmake.exe: Error code 129, while making 'blib\arch\auto\Win32\JobAdd\
+JobAdd.dll
'
Cheers,
Dirk | [reply] [d/l] |
|
And now I get exactly the undefined references which you describe
Heh ... timing. The solution probably hit the list while you were composing your reply ;-)
At least, that *should* be the solution - let us know if it doesn't do the trick for you.
Cheers, Rob
| [reply] |
|
|