Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^3: Read STDOUT from Win32::Job while process is running

by syphilis (Archbishop)
on Mar 09, 2012 at 18:43 UTC ( [id://958777]=note: print w/replies, xml ) Need Help??


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

Replies are listed 'Best First'.
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

      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
      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".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

        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

        Thanks again to all of you helping me so much.

        Here I want to post the solution of my original problem.

        #!/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

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

      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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://958777]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-25 14:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found