Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Webserver and locking

Eathernet Multi-threading

Best Answer hanzibal, 09 July 2013 - 12:58 PM

You should use an interlocked exchange to change the value of the _serverReady varible. The Interlocked.Exchange method will replace the value and return the previous value in a single atomic (unbreakable) operation.

int _serverReady = 1;if(Interlocked.Exchange(ref _serverReady, 0) == 1){            // process request       .      .      .      // done, open unlock the door      _serverReady = 1;}else{      // server busy}
As indicated above, I think you have to declare _serverReady as an integer for this work. You might want to use the volatile modifier on your variable declaration but I don't know if that feally matters in .NETMF. There might also be a way to configure the listener as synchronous so that the server will never attempt to process requests in parallel. Could be this feature is not available in .NETMF, I'm not sure. Go to the full post


  • Please log in to reply
2 replies to this topic

#1 JamieDixon

JamieDixon

    Member

  • Members
  • PipPip
  • 25 posts
  • LocationCary, NC

Posted 08 July 2013 - 04:07 PM

I have worked though the examples on these forums and I don't see an example of my problem.  I want to receive a string message, parse it, and then execute a long-running task (1-15 seconds) using a servo.  While the long running task is executing, I want to respond to any other requests with a 503. 

 

I coded it like this:

1) Have a global variable

private static bool _servoReady = true;

 And then fire up the web server:

        private static void SetUpWebServer()        {            _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, 80);            _serverSocket.Bind(ipEndpoint);            _serverSocket.Listen(10);            ListenForWebRequest();        }

And then handle requests:

        public static void ListenForWebRequest()        {            while (true)            {                using (Socket clientSocket = _serverSocket.Accept())                {                    if (_servoReady)                    {                        _servoReady = false;                        String request = GetRequestFromSocket(clientSocket);                        Thread thread = new Thread(() => HandleWebRequest(request));                        thread.Start();                        SendActivateResponse(clientSocket);                    }                    else                    {                        SendBusyResponse(clientSocket);                    }                }            }        }

 In the HandleWebRequest method, I set the _servoReady to true once the servo work is done.  The servo work looks like this:

        private static void ActivateServoForBellows(String direction, Int32 duration)        {            if (direction == "UP")            {                _servo.Duration = SERVO_UP;            }            else if (direction == "DOWN")            {                _servo.Duration = SERVO_DOWN;            }            Thread.Sleep(duration);            _servo.Duration = SERVO_NEUTRAL;        }

The problem is that this does not work consistently.  I make requests and I get several ActivateResponse messages before the 1st ServerBusy messages.

 

 

I am wondering is I should lock the  _servoReady because I set it to false on the main thread and change it to true on the child tread?  Does anyone have any ideas or better yet, a pattern that seems to match my use case?

 

Thanks in advance.

 

 



#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 09 July 2013 - 12:58 PM   Best Answer

You should use an interlocked exchange to change the value of the _serverReady varible. The Interlocked.Exchange method will replace the value and return the previous value in a single atomic (unbreakable) operation.
int _serverReady = 1;if(Interlocked.Exchange(ref _serverReady, 0) == 1){            // process request       .      .      .      // done, open unlock the door      _serverReady = 1;}else{      // server busy}
As indicated above, I think you have to declare _serverReady as an integer for this work. You might want to use the volatile modifier on your variable declaration but I don't know if that feally matters in .NETMF. There might also be a way to configure the listener as synchronous so that the server will never attempt to process requests in parallel. Could be this feature is not available in .NETMF, I'm not sure.

#3 JamieDixon

JamieDixon

    Member

  • Members
  • PipPip
  • 25 posts
  • LocationCary, NC

Posted 11 July 2013 - 12:28 PM

Thanks Hanzibal:

 

You can see the entire project on my blog here and here.  I will update the webserver component using the Interlocked.Exchange method in a bit.

Also, you can see the Eject-A-Bed in action here.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.