I have an HTTPS server application that uses FreeRTOS.
To protect the access to the useful data to generate the dynamic HTTP files, I added a mutex protection:
openWriter/openWriter are used for HTTP POST requests and openReader/closeReader are used for HTTP GET requests.
When I make HTTP GET requests with a single HTTPS connection, there is no problem but when there are 2 connections, FreeRTOS crashes. If I do not implement this mutex protection, FreeRTOS does not crash.
FreeRTOS does not crash when code is executed between the open/close functions… this is very strange.
I tried increasing the memory allocation for tasks but it’s the same thing.
I have other tasks that use mutexes and there is no problem.
Also, if you need to implement a true R/W lock (either a writer or arbitrarily many readers), the code is not correct as it wii allow readers to enter when a writer is active. In addition, there is deadlock potential in your implementation. I recommend to query this forum for reader/writer lock; the issue has been discussed before.
One possible problem is that muteces can only be released from the same thread that claimed it which may not be guaranteed in your implementation. Try using a binary semaphore for the writer…
When there is a writer, I don’t want to allow a reader. And when there is a reader, I don’t want to allow a writer.
… Where is the problem in my code ?
My application crashes even if there is no writter : I do only HTTP GET requests.
Just a wild guess if this causes a reboot: The crash could be caused by a data corruption.
Did you define configASSERT and also enable stack overflow checking for development/debugging to catch possible fatal errors or data corruptions ?
Are the stack sizes of your tasks large enough ?
One issue you will have is if a higher priority task tries to openWriter(), it will keep on taking the mutex, see that there are readers, give it, then immediately take it again, and not allow the reader to run.
You want a second semaphore (not a mutex) that is taken when ever you bump the readersCounter from 0 to 1, and then given when you bump it down from 1 to 0 that the writer can block on to wait till it has a chance of successfully taking a write lock.
well, the code with the semaphore looks ok now, but the timeouts may be explainable by Richards observations. A lot of read requests will starve the writers… you may need to add additional mechanisms that will allow no more readers when a write request is pending, but since http requests are always read-write, you do not gain a whole lot…
Not only will read requests starve the writer, but a higher trying to get the lock can starve the readers that have the lock from getting any CPU time because it is just polling for the lock to be ready.
A “Good” Read/Write lock takes a bit of thought to do well, and you need to define how you want to manage cases which could cause starvation, and which starvations are important to you.
It confirms that my method is good : it correspond to “prefer reader” mode… but I will change to “prefer writer” mode, it is better for my application.