You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Jan Winter (JIRA)" <ji...@apache.org> on 2016/06/27 13:40:52 UTC

[jira] [Created] (FELIX-5286) Pipe commands run in System.in deadlock on single call.

Jan Winter created FELIX-5286:
---------------------------------

             Summary: Pipe commands run in System.in deadlock on single call. 
                 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:DeadlockSample.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 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;
	}

	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."); // FAILED
				try {
					session.execute("consume | consume");
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("Never reached :("); // DEADLOCK
			}
		});
		deadlockThread.start();
		
		Thread.sleep(1000);
		System.out.println("Exit bevor 'Never reached :(' line is written.");
	}
}
{code}



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