Sending/receiving messages in Erlang (Concurrency) - concurrency

I am trying to solve the following problem:
Write an Erlang function named respond that takes two parameters, a process ID named Pid and an Erlang item named Item. The function should send a message to Pid; the message should be a tuple with two elements: respond’s process ID and Item. Then, the function should wait to receive a message back. If the message it receives is true, then print “That is correct!” If the message it receives is false, then print “That is incorrect!” If the message it receives is an error, then print “There was an error in the input.” If the message is anything else, then print “Invalid message received.”
I have written the following:
respond(Pid,Item) ->
Pid ! {Pid,Item};
receive
true -> io:format(~p~n "That is correct",[]);
false -> io:format(~p~n "That is incorrect",[]);
error -> io:format(~p~n "There was an error in the input",[]);
_ -> io:format(~p~n "Invalid message received",[])
end.
The error that I am getting when I compile my code is as follows:
1> c(main).
main.erl:15: syntax error before: 'receive'
main.erl:2: function respond/2 undefined
error
What is causing this error? Also is my problem solving approach for this Question correct?

You're really really close.
The issue is that expressions in Erlang are not delimited by ;. They're delimited by ,.
Try…
respond(Pid,Item) ->
Pid ! {Pid,Item},
…
Also… a small-ish tip: respond’s process ID is not Pid. To obtain respond’s process ID, you should use self/0.

Related

Formatting output to show in the messages section in error list

I'd like to print a message to the output, not just a warning/error.
For example, you can have:
1>C:\Example Path\Example File.cpp(1): warning EXAMPLE: here is an example warning
1>C:\Example Path\Example File.cpp(1): error EXAMPLE: here is an example error
These following outputs will show up in the error list window. This can be done with #pragma message( ). How can I have something show up as a message, not an error or warning? info and message didn't seem to work.
Messages are broken. Build messages do not show up in the message list.
That said, it's supposed to show up if something is preceded with the "note" flag. There is not code identifier for a message, so it's just "note:"

VS2013 build fails if I output "ERROR" in the post build step - I think

This is a bit of an odd one, and I tried to Google it but didn't have much luck. Also, I apologize for the long lead-in... but I think it's all info necessary to understand what's happening?
I'm working in C++, using Visual Studio 2013, and I have my own unit test implementation. The test project is part of the solution, and there is a post build event which runs them (using the executable which was just built), and if that even returns non-0 then the build fails (as it should).
I also have my own macro-based output system which uses OutputDebugString to print to the output window in the development environment, so I can use statements like these:
AI_ERROR("Some ERROR message with C-style %s", "arguments");
AI_WARN("Some ERROR message with C-style %s", "arguments");
AI_LOG("Some ERROR message with C-style %s", "arguments");
AI_ERROR_CONFIG("Some ERROR message with C-style %s", "arguments");
AI_WARN_CONFIG("Some ERROR message with C-style %s", "arguments");
AI_LOG_CONFIG("Some ERROR message with C-style %s", "arguments");
Which will result in this output when I run the executable directly:
(0.0000) tesaitest.cpp:87 ERROR: Some ERROR message with C-style arguments
(0.0000) tesaitest.cpp:88 WARNING: Some ERROR message with C-style arguments
(0.0000) tesaitest.cpp:89 LOG: Some ERROR message with C-style arguments
(0.0000) tesaitest.cpp:90 ERROR (CONFIGURATION): Some ERROR message with C-style arguments
(0.0000) tesaitest.cpp:91 WARNING (CONFIGURATION): Some ERROR message with C-style arguments
(0.0000) tesaitest.cpp:92 LOG (CONFIGURATION): Some ERROR message with C-style arguments
That all works - so far so good.
Here's where it gets a little weird. If I run the executable for the tests directly, then it runs, and it prints the messages I showed above, and it returns 0 - which is expected, since I never wrote any code to do anything different. However, when I compile and the tests are run as a post build event, it returns -1. If I comment out the two error messages (the AI_ERROR and the AI_ERROR_CONFIG) then it returns 0, even though the output string still has the word "ERROR" in it. This is actually the behavior I want - but this is a multi-compiler project, and I want to make sure that execution is consistent, so I want to make sure that I'm the one making it happen, not just the dev environment doing it for me.
Another thing that I notice is that in the output that I get when I compile, the words "error" and "warning" are lower case, but "log" is not - and they are not lowercase in the original code. Here's what that output looks like:
1>(0.0000) tesaitest.cpp : 87 error : Some ERROR message with C-style arguments
1>(0.0000) tesaitest.cpp : 88 warning : Some ERROR message with C-style arguments
1> (0.0000) tesaitest.cpp:89 LOG: Some ERROR message with C-style arguments
1>(0.0000) tesaitest.cpp : 90 error (CONFIGURATION): Some ERROR message with C-style arguments
1>(0.0000) tesaitest.cpp : 91 warning (CONFIGURATION): Some ERROR message with C-style arguments
1> (0.0000) tesaitest.cpp:92 LOG (CONFIGURATION): Some ERROR message with C-style arguments
That part of the string is passed into the print function as an enum (either Error or ConfigError), but then I use vsnprintf_s to compile the whole message into a single char buffer before I pass it into OutputDebugString.
Of course, for added fun, because this only happens during compile, and not when I run the executable directly, I can't catch it in the debugger.
So... does anybody understand how/why MS is determining that these are errors and changing the return value? Is there a setting where I can turn that off? As I said, since this is a multi-compiler project, and also because I might want to be able to have cases where error messages don't actually represent failed tests (i.e. I want to test that error messages to get generated on bad input) I'd rather that I had full control over the return value...

FindNextPrinterChangeNotification returns NULL for ppPrinterNotifyInfo

I'm stuck on problem were I would like to ask for some help:
I have the task to print some files of different types using ShellExecuteEx with the "print" verb and need to guarantee print order of all files. Therefore I use FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification to monitor the events PRINTER_CHANGE_ADD_JOB and PRINTER_CHANGE_DELETE_JOB using two different threads in the background which I start before calling ShellExecuteEx as I don't know anything about the application which will print the files etc. The only thing I know is that I'm the only one printing and which file I print. My solution seems to work well, my program successfully recognizes the event PRINTER_CHANGE_ADD_JOB for my file, I even verify that this event is issued for my file by checking what is give to me as additional info by specifying JOB_NOTIFY_FIELD_DOCUMENT.
The problem now is with the event PRINTER_CHANGE_DELETE_JOB, where I don't get any addition info about the print job, though my logic is exactly the same for both events: I've written one generic thread function which simply gets executed with the event it is used for. My thread is recognizing the PRINTER_CHANGE_DELETE_JOB event, but on each call to FindNextPrinterChangeNotification whenever this event occured I don't get any addition data in ppPrinterNotifyInfo. This works for the start event, though, I verified using my logs and the debugger. But with PRINTER_CHANGE_DELETE_JOB the only thing I get is NULL.
I already searched the web and there are some similar questions, but most of the time related to VB or simply unanswered. I'm using a C++ project and as my code works for the ADD_JOB-event I don't think I'm doing something completely wrong. But even MSDN doesn't mention this behavior and I would really like to make sure that the DELETE_JOB event is the one for my document, which I can't without any information about the print job. After I get the DELETE_JOB event my code doesn't even recognize other events, which is OK because the print job is done afterwards.
The following is what I think is the relevant notification code:
WORD jobNotifyFields[1] = {JOB_NOTIFY_FIELD_DOCUMENT};
PRINTER_NOTIFY_OPTIONS_TYPE pnot[1] = {JOB_NOTIFY_TYPE, 0, 0, 0, 1, jobNotifyFields};
PRINTER_NOTIFY_OPTIONS pno = {2, 0, 1, pnot};
HANDLE defaultPrinter = PrintWaiter::openDefaultPrinter();
HANDLE changeNotification = FindFirstPrinterChangeNotification( defaultPrinter,
threadArgs->event,
0, &pno);
[...]
DWORD waitResult = WAIT_FAILED;
while ((waitResult = WaitForSingleObject(changeNotification, threadArgs->wfsoTimeout)) == WAIT_OBJECT_0)
{
LOG4CXX_DEBUG(logger, L"Irgendein Druckereignis im Thread zum Warten auf Ereignis " << LogStringConv(threadArgs->event) << L" erkannt.");
[...]
PPRINTER_NOTIFY_INFO notifyInfo = NULL;
DWORD events = 0;
FindNextPrinterChangeNotification(changeNotification, &events, NULL, (LPVOID*) &notifyInfo);
if (!(events & threadArgs->event) || !notifyInfo || !notifyInfo->Count)
{
LOG4CXX_DEBUG(logger, L"unpassendes Ereignis " << LogStringConv(events) << L" ignoriert");
FreePrinterNotifyInfo(notifyInfo);
continue;
}
[...]
I would really appreciate if anyone could give some hints on why I don't get any data regarding the print job. Thanks!
https://forums.embarcadero.com/thread.jspa?threadID=86657&stqc=true
Here's what I think is going on:
I observe two events in two different threads for the start and end of each print job. With some debugging and logging I recognized that FindNextPrinterChangeNotification doesn't always return only the two distinct events I've notified for, but some 0-events in general. In those cases FindNextPrinterChangeNotification returns 0 as the events in pdwChange. If I print a simple text file using notepad.exe I only get one event for creation of the print job with value 256 for pdwChange and the data I need in notifyInfo to compare my printed file name against and comparing both succeeds. If I print a pdf file using current Acrobat Reader 11 I get two events, one has pdwChange as 256, but gives something like "local printdatafile" as the name of the print job started, which is obviously not the file I printed. The second event has a pdwChange of 0, but the name of the print job provided in notifyInfo is the file name I used to print. As I use FreePDF for testing pruproses, I think the first printer event is something internal to my special setup.
The notifications for the deletion of a print job create 0 events, too. This time those are sent before FindNextPrinterChangeNotification returns 1024 in pdwChange, and timely very close after the start of the print job. In this case the exactly one generated 0 event contains notifyInfo with a document name which equals the file name I started printing. After the 0 event there's exactly one additional event with pdwChange of 1024, but without any data for notifyInfo.
I think Windows is using some mechanism which provides additional notifications for the same event as 0 events after the initial event has been fired with it's real value the user notified with, e.g. 256 for PRINTER_CHANGE_ADD_JOB. On the other hand it seems that some 0 events are simply fired to provide data for an upcoming event which then gets the real value of e.g. 1024 for PRINTER_CHANGE_DELETE_JOB, but without anymore data because that has already been delivered to the event consumer with a very early 0 event. Something like "Look, there's more for the last events." and "Look, something is going to happen with the data I already provide now." Implementing such an approach my prints now seem to work as expected.
Of course what I wrote doesn't fit to what is documented for FindNextPrinterChangeNotification, but it makes a bit of sense to me. ;-)
You're not checking for overflows or errors.
The documentation for FindNextPrinterChangeNotification says this:
If the PRINTER_NOTIFY_INFO_DISCARDED bit is set in the Flags member of
the PRINTER_NOTIFY_INFO structure, an overflow or error occurred, and
notifications may have been lost. In this case, no additional
notifications will be sent until you make a second
FindNextPrinterChangeNotification call that specifies
PRINTER_NOTIFY_OPTIONS_REFRESH.
You need to check for that flag and do as described above, and you should also be checking the return code from FindNextPrinterChangeNotification.

How to get the status of printer and the job sent to a printer using wxWidgets

How to get the status of printer and the job sent to a printer using wxWidgets.
Find the printer.
Things I have to do is:
1. Find a printer.
2. Check the status of the printer.
3. Send the job to print.
4. Return ack after the job fails/Completes.
Thanks in advance.
Have you studied the wxWidgets printing overview?
http://docs.wxwidgets.org/stable/wx_printingoverview.html
You can query the last error right after the call to print, like this:
wxPrinter printer;
MyPrintout printout("My printout");
printer.Print(this, &printout, true);
wxPrinterError errorCode = printer.GetLastError();
The return values can be:
wxPRINTER_NO_ERROR No error happened.
wxPRINTER_CANCELLED The user cancelled printing.
wxPRINTER_ERROR There was an error during printing.
For further reference check here: http://docs.wxwidgets.org/stable/wx_wxprinter.html#wxprinterprint

List of PID's in Erlang

Long story short I am trying to replicate the Sleeping barber problem in Erlang.
In my solution I decided that for all the processes that are waiting I would put them into a list. Then, once it was that processes turn, I would take that PID off of the list.
Unfortunately when I call
length(myListOfPids).
it fails, as an example:
length([<0.46.0>]).
* 2: syntax error before: '<'
is there a way to store PID's so that I can recall them and use them normally? i.e.
PID ! message
... just in case it matters here is the actual error I recieve when running my program:
=ERROR REPORT==== 1-Jul-2010::05:50:40 ===
Error in process <0.44.0> with exit value:
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}
barber1 is my module, waitingRoom is the function that keeps track of which processes are waiting
You can also construct a Pid from it's three components using pid/3.
1> length([pid(0,35,0)]).
Be aware that using any of these techniques for constructing Pid goes wrong if you construct a pid on a different node than the one it was created on.
The problem your program is having is different.
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}
A call to erlang:length/1 created a badarg. The third element of {erlang,length,[<0.46.0>]} is the list of arguments passed to erlang:length. So that's equivalent to:
1> erlang:length(pid(0,46,0)).
where you intended:
1> erlang:length([pid(0,46,0)]).
(Annoyingly, the erlang shell now hides erlang's internal representation of errors from you. Replacing the above error with:
** exception error: bad argument in function length/1 called as length(<0.35.0>)
which is much easier to understand but less useful because it gets in the way of learning the essential skill of interpreting erlang errors yourself.)
Entering Pids by typing them does not work for me either.
Is that the only problem?
With code:
-module(test).
-export([loop/0]).
loop() ->
receive
{hello} ->
io:format("Hello world!~n"),
loop()
end.
I get:
Eshell V5.7.5 (abort with ^G)
1> Pid = spawn(fun test:loop/0).
<0.35.0>
2> L = [Pid].
[<0.35.0>]
3> length(L).
1
This error message:
=ERROR REPORT==== 1-Jul-2010::05:50:40 ===
Error in process <0.44.0> with exit value:
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}
means that you were calling length(<0.46.0>), not length([<0.46.0>]) (ignoring for the moment that PIDs can only be written, not read). In the stack trace the topmost function will have the list of arguments. Since length takes one argument, this list has a single argument: you are taking the length of a PID, which obviously fails, since only lists have lengths.
The problem is that while <0.46.0> is the way that a PID gets printed, it can't be entered this way. You can use list_to_pid("<0.46.0>") instead. Of course, once you do have a PID (created in this way, returned from spawn, etc.), it can be stored in a list and retrieved like any other Erlang term.
The standard way to get a pid is to take the return value of a spawn function, either spawn/1, spawn/3, spawn_link/1, spawn_link/3, and the proc_lib equivalents.
A simple way to write down a pid is with the function c:pid/3, called like c:pid(0,25,0), which will return <0.25.0>. That's a shortcut function for the shell. Otherwise, you can use list_to_pid/1 as mentioned by Alexey Romanov.
However, you should be aware of the role of pids before trying to build them by hand. The pid acts as the personal identifier of a process and is meant to be used only by those who know about it. If you don't have the pid in your hand already, then you likely shouldn't be in its possession already. Indirectly, this is meant to lead to insulation of different parts of a program — only care about those bits that you spawned and have each part of your program mind its own business.
The cleanest way to do it is thus to use the return value of a spawn function. Generating a pid by hand should be left as a debugging solution only.