thread-regular.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package frankenphp
  2. // #include "frankenphp.h"
  3. import "C"
  4. import (
  5. "net/http"
  6. )
  7. // representation of a non-worker PHP thread
  8. // executes PHP scripts in a web context
  9. // implements the threadHandler interface
  10. type regularThread struct {
  11. state *threadState
  12. thread *phpThread
  13. activeRequest *http.Request
  14. }
  15. func convertToRegularThread(thread *phpThread) {
  16. thread.setHandler(&regularThread{
  17. thread: thread,
  18. state: thread.state,
  19. })
  20. }
  21. // beforeScriptExecution returns the name of the script or an empty string on shutdown
  22. func (handler *regularThread) beforeScriptExecution() string {
  23. switch handler.state.get() {
  24. case stateTransitionRequested:
  25. return handler.thread.transitionToNewHandler()
  26. case stateTransitionComplete:
  27. handler.state.set(stateReady)
  28. return handler.waitForRequest()
  29. case stateReady:
  30. return handler.waitForRequest()
  31. case stateShuttingDown:
  32. // signal to stop
  33. return ""
  34. }
  35. panic("unexpected state: " + handler.state.name())
  36. }
  37. // return true if the worker should continue to run
  38. func (handler *regularThread) afterScriptExecution(exitStatus int) {
  39. handler.afterRequest(exitStatus)
  40. }
  41. func (handler *regularThread) getActiveRequest() *http.Request {
  42. return handler.activeRequest
  43. }
  44. func (handler *regularThread) waitForRequest() string {
  45. select {
  46. case <-handler.thread.drainChan:
  47. // go back to beforeScriptExecution
  48. return handler.beforeScriptExecution()
  49. case r := <-requestChan:
  50. handler.activeRequest = r
  51. fc := r.Context().Value(contextKey).(*FrankenPHPContext)
  52. if err := updateServerContext(handler.thread, r, true, false); err != nil {
  53. rejectRequest(fc.responseWriter, err.Error())
  54. handler.afterRequest(0)
  55. // go back to beforeScriptExecution
  56. return handler.beforeScriptExecution()
  57. }
  58. // set the scriptFilename that should be executed
  59. return fc.scriptFilename
  60. }
  61. }
  62. func (handler *regularThread) afterRequest(exitStatus int) {
  63. fc := handler.activeRequest.Context().Value(contextKey).(*FrankenPHPContext)
  64. fc.exitStatus = exitStatus
  65. maybeCloseContext(fc)
  66. handler.activeRequest = nil
  67. }