C++ pipe process not terminating - process

I made a program that takes two commands typed in by the user and pipes the first into the second. It works fine if real commands are entered but I'm having a problem getting my error check to work when I just enter random words. In most places of my code where I use exit() the process terminates fine but within the two child processes rs1 and rs2, I cannot exit. I'm new to processes so I'm not sure how to do this correctly. Can someone help?
int main()
{
while(true)
{
int argc1=0,argc2=0,rs1,rs2,pipefd[2];
char input1[80],input2[80],*argv1[6],*argv2[6],*p1,*p2;
//*Big block of code that receives input goes here*
pipe(pipefd);
rs1=fork();
rs2=fork();
if(rs1==0)
{
close(pipefd[0]);
close(1);
dup(pipefd[1]);
close(pipefd[1]);
rs1=execvp(argv1[0],argv1);
if(rs1==-1)
{
perror(argv1[0]);
exit(rs1); //Here is where I'm having the problem
}
}
if(rs2==0)
{
close(pipefd[1]);
close(0);
dup(pipefd[0]);
close(pipefd[0]);
rs2=execvp(argv2[0],argv2);
if(rs2==-1)
{
perror(argv2[0]);
exit(rs2); //Here also does not work correctly
}
}
close(pipefd[0]);
close(pipefd[1]);
wait(&rs1);
wait(&rs2);
}
return 0;
}

Related

is whenever signal() in react block order dependent?

I have a small program which runs until a SIGINT is received or two lines (press enter twice) from stdin are received. The react block logic is:
react {
whenever signal(SIGINT) {
say "Got signal";
exit;
}
whenever $*IN.lines.Supply {
say "Got line";
exit if $++ == 1 ;
}
}
Program will exit on two entered lines as expected.
However CTRL-C will not do anything, unless it is followed by a line (enter).
If I switch the order of the whenever blocks, the program is interrupted by a SIGINT but doesn't execute the signal whenever block
react {
whenever $*IN.lines.Supply {
say "Got line";
exit if $++ == 1 ;
}
whenever signal(SIGINT) {
say "Got signal";
exit;
}
}
Is there some other setup required before using the signal sub? Is the order of whenever blocks important in a react block?
Update
So it seems the lines() call is blocking the react block from executing (thanks #HÃ¥kon). I kind of get it.
When comparing to a similar code structure for reading a socket I'm confused though. The presence of data (or lack of) has no effect on the signal handler executing and it can read lines just fine in this example:
my $listener=IO::Socket::Async.listen("0.0.0.0",4432);
react {
whenever $listener {
whenever $_.Supply.lines() {
say "Got line";
}
}
whenever signal(SIGINT) {
say "Got signal";
exit;
}
}
#testing with:
# curl http://localhost:4432
Why does this behave so different to my original code?
The order doesn't matter provided the data sources really behave in an asynchronous manner, which unfortunately is not the case here. The Supply coercer on a Seq does not introduce any concurrency, and does immediately try to produce a value to emit on the Supply, which in turn blocks on reading from $*IN. Thus, the second subscription doesn't have chance to be set up; the same underlying issue causes the other problems observed.
The solution is to force the reading to happen "elsewhere". We can do that with Supply.from-list(...), plus telling it we really do want to use the current scheduler rather than its default CurrentThreadScheduler. Thus, this behaves as wanted:
react {
whenever Supply.from-list($*IN.lines, scheduler => $*SCHEDULER) {
say "Got line";
exit if $++ == 1 ;
}
whenever signal(SIGINT) {
say "Got signal";
exit;
}
}
It's likely this area will be revised somewhat in future Perl 6 versions. The current behavior was well-intended; the design principle was to avoid implicit introduction of concurrency, following the general principle that supplies are a tool for managing concurrency that inherently exists, rather than for introducing it. However, in reality, the lack of concurrency here has probably tripped up more folks than it has helped. (Further, we may look into offering real non-blocking file I/O, rather than building it from sync file I/O + threads.)
Here is a variant that runs the signal handler (based on this answer), but unfortunately autoflushing of $*IN seems to be turned off:
my $lines = supply {
whenever start $*IN.lines.Supply {
whenever .lines { .emit }
}
}.Channel;
react {
whenever signal(SIGINT) {
say "Got signal";
exit;
}
whenever $lines {
say "Got line: '{$_}'";
exit if $++ == 1;
}
}
Now you have to press CTRL-D to print the lines, and then it print all lines entered as a concatenated string and after that $*IN is closed.. How can I turn on autoflushing for $*IN in this case?

How to modify a form in a background thread

This might be a simple question but I can't figure it out.
I have a form called in my main function:
void Main() {
Mem = new MemoryManager();
Console::WriteLine("Thread Started");
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
FinalSolution::ControlPanel form;
Thread^ cLoop = gcnew Thread(gcnew ThreadStart(loop));
cLoop->Start();
Application::Run(%form);
}
All I want to do is, if someone presses a key in general (not just when the program is in focus), it changes the background to a different color.
I have tried a few things but nothing has worked so far. Here is the loop and I have indicated where I want it to happen.
void loop() {
while (true) {
if (GetAsyncKeyState(key)) {
//Here
form.button->BackColor = System::Drawing::Color::ForestGreen;
}
}
}
Of course the issue is that this function doesn't know what form is, but I don't know how to tell it.
Ended up just putting the loop directly in the form header and that solved the problem.

Issue with syncing data between watch and phone

I have developed an Android App which runs on both a smartphone and a smartwatch in parallel. On both devices, (let's say) it reads certain sensor data, processes that data (calculate its mean), and then store that results. The watch sends this result to the phone so all storing takes place on the phone. I used buffer writer to write a number into a text file every 5 seconds.
Now after every 320 data items exchanges from watch to the phone, my app on the phone gets killed and I get "the name of the app" is unfortunately stopped as a message. I can't figure it what why they stop exactly after this time? The app running on the watch continues to work fine. However, I cannot store its data because it cannot communicate to the phone version so I get this message "the app is unfortunately stopped as a message" every time the watch sends a number to phone for storing. The app has one activity which has a service (foreground).
Could it be that there is a limit on the amount of data being shared?
The code on watch:
// Create a data map and put data in it
private void increaseCounter() {
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt(COUNT_KEY, count++); // I add current time here as well
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult =
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
}
Code on phone (possible problematic area):
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo("/count") == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
updateCount(dataMap.getInt(COUNT_KEY));
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
}
You have to use Service with StartForeground notification to be sure app is always working.
and try to use START_STICKY flag while staring.
UPDATE
You have to dealloc memory of dataevent:
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
try{
for(DataEvent dataEvent: dataEvents){
if(dataEvent.getType() != DataEvent.TYPE_CHANGED){
continue;
}
////... code
dataEvents.release();
}catch (Exception e){
Log.v("SunshineWatchFace",e.getMessage());
}
}

selenium webdriver sendkeys intermittent issue

I have a web automation framework set up that works pretty well. I have a constant issue though that when using SendKeys to write to textboxes, quite often a letter gets missed out. So for example, if my dataset is "TestUserName", something like "TestUerName" gets sent example with a missing letter.
This is a big issue for me, as after the web tests concludes successfully I further check if the database was updated properly. So in the above example I would go to the UserName column and expect to find TestUserName, but the test would fail because TestUerName is found instead.
Any ideas please? I am using selenium 2.53.0.
My code below.
public void inputValue (Object [][] valuesFromExcel)
{
for (int rowNow = 0; rowNow < (valuesFromExcel.length); rowNow++)
{
String newValue = valuesFromExcel[rowNow][0].toString();
if (!newValue.equals(""))
{
WebElement currentElement = driver.findElement(By.id(valuesFromExcel[rowNow][1].toString()));
if (currentElement.getTagName().equals("input"))
{
currentElement.sendKeys(newValue);
}
else if (currentElement.getTagName().equals("select"))
{
new Select(currentElement).selectByVisibleText(newValue);
}
}
}
}
Thanks.
Instead of sending as a string, send it as char...
Convert the string to char and send each char one by one to the text box. Yes there will be a performance issue, but it works fine. It will not skip any of the letters

Monotouch: UIAlertView and WCF services, debugger.StackTrace

I'm currently using WCF in monotouch to call an existing service and a custom UIAlertView.
The problem is that if I create an UIAlertView as class instance and the I do the following:
public override void ViewDidAppear()
{
_alertView.Message = "Loading...";
_alertView.Show();
_client.GetDataAsync("test");
_client.GetDataCompleted += GetDataCompletedDelegate;
base.ViewDidAppear();
}
void GetDataCompletedDelegate(object sender, GetDataEventArgs)
{
// do someting with data
_alertView.Hide();
}
it works but this advice is written in console : UIAlertView: wait_fences: failed to receive reply: 10004003
else, if I try to run this code:
public override void ViewDidAppear()
{
using(CustomAV _alertView = new CustomAV())
{
_alertView.Message = "Loading...";
_alertView.Show();
_client.GetDataAsync("test");
_client.GetDataCompleted += delegate{
InvokeOnMainThread(delegate{
// do someting with data
_alertView.Hide();
});
};
}
base.ViewDidAppear();
}
the first time the code run, but now alert is shown. The second time the simulator can't startup. Couldn't register "com.yourcompany.wcftest" with the bootstrap server. Error: unknown error code. This generally means that another instance of this process was already running or is hung in the debugger.StackTrace. In this case I have to reboot the machine.
Thank you in advance.
EDIT:
Thank you Geoff, I've checked my code and into GetDataCompletedDelegate I've inserted a function that runs inside the UI Thread.
InvokeOnMainThread(delegate{
doSomething();
});
private void doSomething()
{
// do stuff here
_alertView.Hide();
}
The fency error continues to appear. If I use your solution inside doSomething() method, it works
_alertView.InvokeOnMainThread(delegate{
_alertView.Hide();
});
Why? Maybe I didn't understand, but in the first snippet of code do something() works in the UI thread!! Isn't true?
You have 2 seperate problems here.
1: _alertView.Hide () is not running on the UI thread (this is what causes the fences error)
2: In your second example you're disposing the UIAlertVeiw immediately after creating it, but you have a instance delegate dangled off it. This crashes the runtime in a hard way, and then when you run it again since the old crashed process is still running the simulator wont let you start a second instance.
Use case #1 but do _alterView.InvokeOnMainThread (delegate { _alertView.Hide (); });