felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jan Winter (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (FELIX-5286) Pipe commands like 'grep' run in System.in deadlock in pipeless mode.
Date Tue, 28 Jun 2016 08:21:57 GMT

     [ https://issues.apache.org/jira/browse/FELIX-5286?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Jan Winter updated FELIX-5286:
------------------------------
    Description: 
{code}
g! grep 'test'
# DEADLOCK !!! Java process must be killed. 
{code}

*My 'produce | consume' sample*: 

{code:java}
package gogo.runtime.deadlock;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

import org.apache.felix.gogo.runtime.CommandProcessorImpl;
import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
import org.apache.felix.service.command.CommandSession;

public class Main {

	public static void main(String[] args) throws Exception {
		ThreadIOImpl tio = new ThreadIOImpl();
		tio.start();
		
		CommandProcessorImpl processor = new CommandProcessorImpl(tio);
		DeadlockSample commands = new DeadlockSample();
		
		processor.addCommand("deadlock", commands, "produce");
		processor.addCommand("deadlock", commands, "consume");
		
		CommandSession session = processor.createSession(System.in, System.out, System.err);
		
		session.execute("produce"); // SUCC
		session.execute("consume"); // SUCC
		session.execute("produce | consume"); //SUCC
		
		Thread deadlockThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("'consume | consume' pipe run in deadlock."); 
				try {
					session.execute("consume | consume"); // DEADLOCK
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("Never reached :("); 
			}
		});
		deadlockThread.start();
		
		Thread.sleep(1000);
		System.out.println("Exit bevor 'Never reached :(' line is written.");
                
                System.exit(0);
	}

	public static class DeadlockSample{
		public void produce(){
			System.out.println(Math.random());
		}
		
		public void consume() throws IOException{
			List<String> lines = readSysin();
			
			if(lines.isEmpty()){
				System.out.println("'consume' execution is catched by thread-name != 'pipe-...': '" +
Thread.currentThread().getName() + "'");
				return;
			}
			
			for (String line : lines) {
				System.out.println("'consume' " + line);
			}
		}
	}
	
	public static List<String> readSysin() throws IOException {
		final List<String> lines = new LinkedList<String>();

		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		String lastLine = null;
		boolean isFirstLine = true;
		boolean hasNoInput = false;

		while (true) {
			if (hasNoInput) {
				break;
			}
			String line = null;

			if (isFirstLine) {
				isFirstLine = false;
				boolean isSysinAvailable = System.in.available() != 0;
				boolean isPipedGogoThread = Thread.currentThread().getName().startsWith("pipe-");
				
				if (isSysinAvailable || isPipedGogoThread) {
					line = reader.readLine();
				}
			} else
				line = reader.readLine();

			if (line == null) {
				hasNoInput = true;
				
				boolean isPreviousLineNull = lastLine == null;
				if(isPreviousLineNull)
					continue;
				
				switch (lastLine) {
				case "":
				case "true":
				case "false":
					lines.remove(lines.size() - 1);
					break;
				default:
					continue;
				}
				continue;
			}
			lines.add(line);
			lastLine = line;
		}
		return lines;
	}
}
{code}

I expect following output: 

{noformat}
0.8792454918763092
'consume' execution is catched by thread-name != 'pipe-...': 'main'
'consume' 0.15400105033134115
'consume | consume' pipe run in deadlock.
Exit bevor 'Never reached :(' line is written.
{noformat}

I want to implement commands where it does not matter that the input came from System.in or
as Arg. Unfortunately its impossible to check the System.in that nothing is coming.


  was:
{code}
g! grep 'test'
# DEADLOCK !!! Java process must be killed. 
{code}

*My 'produce | consume' sample*: 

{code:java}
package gogo.runtime.deadlock;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

import org.apache.felix.gogo.runtime.CommandProcessorImpl;
import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
import org.apache.felix.service.command.CommandSession;

public class Main {

	public static void main(String[] args) throws Exception {
		ThreadIOImpl tio = new ThreadIOImpl();
		tio.start();
		
		CommandProcessorImpl processor = new CommandProcessorImpl(tio);
		DeadlockSample commands = new DeadlockSample();
		
		processor.addCommand("deadlock", commands, "produce");
		processor.addCommand("deadlock", commands, "consume");
		
		CommandSession session = processor.createSession(System.in, System.out, System.err);
		
		session.execute("produce"); // SUCC
		session.execute("consume"); // SUCC
		session.execute("produce | consume"); //SUCC
		
		Thread deadlockThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("'consume | consume' pipe run in deadlock."); 
				try {
					session.execute("consume | consume"); // DEADLOCK
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("Never reached :("); 
			}
		});
		deadlockThread.start();
		
		Thread.sleep(1000);
		System.out.println("Exit bevor 'Never reached :(' line is written.");
                
                deadlockThread.interrupt();
	}

	public static class DeadlockSample{
		public void produce(){
			System.out.println(Math.random());
		}
		
		public void consume() throws IOException{
			List<String> lines = readSysin();
			
			if(lines.isEmpty()){
				System.out.println("'consume' execution is catched by thread-name != 'pipe-...': '" +
Thread.currentThread().getName() + "'");
				return;
			}
			
			for (String line : lines) {
				System.out.println("'consume' " + line);
			}
		}
	}
	
	public static List<String> readSysin() throws IOException {
		final List<String> lines = new LinkedList<String>();

		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		String lastLine = null;
		boolean isFirstLine = true;
		boolean hasNoInput = false;

		while (true) {
			if (hasNoInput) {
				break;
			}
			String line = null;

			if (isFirstLine) {
				isFirstLine = false;
				boolean isSysinAvailable = System.in.available() != 0;
				boolean isPipedGogoThread = Thread.currentThread().getName().startsWith("pipe-");
				
				if (isSysinAvailable || isPipedGogoThread) {
					line = reader.readLine();
				}
			} else
				line = reader.readLine();

			if (line == null) {
				hasNoInput = true;
				
				boolean isPreviousLineNull = lastLine == null;
				if(isPreviousLineNull)
					continue;
				
				switch (lastLine) {
				case "":
				case "true":
				case "false":
					lines.remove(lines.size() - 1);
					break;
				default:
					continue;
				}
				continue;
			}
			lines.add(line);
			lastLine = line;
		}
		return lines;
	}
}
{code}

I expect following output: 

{noformat}
0.8792454918763092
'consume' execution is catched by thread-name != 'pipe-...': 'main'
'consume' 0.15400105033134115
'consume | consume' pipe run in deadlock.
Exit bevor 'Never reached :(' line is written.
{noformat}

I want to implement commands where it does not matter that the input came from System.in or
as Arg. Unfortunately its impossible to check the System.in that nothing is coming.



> Pipe commands like 'grep' run in System.in deadlock in pipeless mode. 
> ----------------------------------------------------------------------
>
>                 Key: FELIX-5286
>                 URL: https://issues.apache.org/jira/browse/FELIX-5286
>             Project: Felix
>          Issue Type: Bug
>          Components: Gogo Runtime
>    Affects Versions: gogo.runtime-0.16.4
>         Environment: macos
>            Reporter: Jan Winter
>
> {code}
> g! grep 'test'
> # DEADLOCK !!! Java process must be killed. 
> {code}
> *My 'produce | consume' sample*: 
> {code:java}
> package gogo.runtime.deadlock;
> import java.io.BufferedReader;
> import java.io.IOException;
> import java.io.InputStreamReader;
> import java.util.LinkedList;
> import java.util.List;
> import org.apache.felix.gogo.runtime.CommandProcessorImpl;
> import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
> import org.apache.felix.service.command.CommandSession;
> public class Main {
> 	public static void main(String[] args) throws Exception {
> 		ThreadIOImpl tio = new ThreadIOImpl();
> 		tio.start();
> 		
> 		CommandProcessorImpl processor = new CommandProcessorImpl(tio);
> 		DeadlockSample commands = new DeadlockSample();
> 		
> 		processor.addCommand("deadlock", commands, "produce");
> 		processor.addCommand("deadlock", commands, "consume");
> 		
> 		CommandSession session = processor.createSession(System.in, System.out, System.err);
> 		
> 		session.execute("produce"); // SUCC
> 		session.execute("consume"); // SUCC
> 		session.execute("produce | consume"); //SUCC
> 		
> 		Thread deadlockThread = new Thread(new Runnable() {
> 			
> 			@Override
> 			public void run() {
> 				System.out.println("'consume | consume' pipe run in deadlock."); 
> 				try {
> 					session.execute("consume | consume"); // DEADLOCK
> 				} catch (Exception e) {
> 					e.printStackTrace();
> 				}
> 				System.out.println("Never reached :("); 
> 			}
> 		});
> 		deadlockThread.start();
> 		
> 		Thread.sleep(1000);
> 		System.out.println("Exit bevor 'Never reached :(' line is written.");
>                 
>                 System.exit(0);
> 	}
> 	public static class DeadlockSample{
> 		public void produce(){
> 			System.out.println(Math.random());
> 		}
> 		
> 		public void consume() throws IOException{
> 			List<String> lines = readSysin();
> 			
> 			if(lines.isEmpty()){
> 				System.out.println("'consume' execution is catched by thread-name != 'pipe-...':
'" + Thread.currentThread().getName() + "'");
> 				return;
> 			}
> 			
> 			for (String line : lines) {
> 				System.out.println("'consume' " + line);
> 			}
> 		}
> 	}
> 	
> 	public static List<String> readSysin() throws IOException {
> 		final List<String> lines = new LinkedList<String>();
> 		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
> 		String lastLine = null;
> 		boolean isFirstLine = true;
> 		boolean hasNoInput = false;
> 		while (true) {
> 			if (hasNoInput) {
> 				break;
> 			}
> 			String line = null;
> 			if (isFirstLine) {
> 				isFirstLine = false;
> 				boolean isSysinAvailable = System.in.available() != 0;
> 				boolean isPipedGogoThread = Thread.currentThread().getName().startsWith("pipe-");
> 				
> 				if (isSysinAvailable || isPipedGogoThread) {
> 					line = reader.readLine();
> 				}
> 			} else
> 				line = reader.readLine();
> 			if (line == null) {
> 				hasNoInput = true;
> 				
> 				boolean isPreviousLineNull = lastLine == null;
> 				if(isPreviousLineNull)
> 					continue;
> 				
> 				switch (lastLine) {
> 				case "":
> 				case "true":
> 				case "false":
> 					lines.remove(lines.size() - 1);
> 					break;
> 				default:
> 					continue;
> 				}
> 				continue;
> 			}
> 			lines.add(line);
> 			lastLine = line;
> 		}
> 		return lines;
> 	}
> }
> {code}
> I expect following output: 
> {noformat}
> 0.8792454918763092
> 'consume' execution is catched by thread-name != 'pipe-...': 'main'
> 'consume' 0.15400105033134115
> 'consume | consume' pipe run in deadlock.
> Exit bevor 'Never reached :(' line is written.
> {noformat}
> I want to implement commands where it does not matter that the input came from System.in
or as Arg. Unfortunately its impossible to check the System.in that nothing is coming.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message