unicorn 5.4.1 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.manifest +10 -5
  3. data/.olddoc.yml +15 -7
  4. data/Application_Timeouts +4 -4
  5. data/CONTRIBUTORS +6 -2
  6. data/Documentation/.gitignore +1 -3
  7. data/Documentation/unicorn.1 +222 -0
  8. data/Documentation/unicorn_rails.1 +207 -0
  9. data/FAQ +1 -1
  10. data/GIT-VERSION-FILE +1 -1
  11. data/GIT-VERSION-GEN +1 -1
  12. data/GNUmakefile +112 -57
  13. data/HACKING +2 -9
  14. data/ISSUES +29 -33
  15. data/KNOWN_ISSUES +2 -2
  16. data/LATEST +16 -21
  17. data/LICENSE +2 -2
  18. data/Links +13 -11
  19. data/NEWS +197 -0
  20. data/README +27 -14
  21. data/SIGNALS +1 -1
  22. data/Sandbox +5 -5
  23. data/archive/slrnpull.conf +1 -1
  24. data/bin/unicorn +3 -1
  25. data/bin/unicorn_rails +2 -2
  26. data/examples/big_app_gc.rb +1 -1
  27. data/examples/logrotate.conf +3 -3
  28. data/examples/nginx.conf +4 -3
  29. data/examples/unicorn.conf.minimal.rb +2 -2
  30. data/examples/unicorn.conf.rb +2 -2
  31. data/examples/unicorn@.service +7 -0
  32. data/ext/unicorn_http/c_util.h +5 -13
  33. data/ext/unicorn_http/common_field_optimization.h +23 -6
  34. data/ext/unicorn_http/epollexclusive.h +124 -0
  35. data/ext/unicorn_http/ext_help.h +0 -24
  36. data/ext/unicorn_http/extconf.rb +32 -6
  37. data/ext/unicorn_http/global_variables.h +3 -3
  38. data/ext/unicorn_http/httpdate.c +3 -2
  39. data/ext/unicorn_http/unicorn_http.c +262 -237
  40. data/ext/unicorn_http/unicorn_http.rl +52 -27
  41. data/lib/unicorn/configurator.rb +25 -4
  42. data/lib/unicorn/http_request.rb +12 -3
  43. data/lib/unicorn/http_server.rb +62 -36
  44. data/lib/unicorn/launcher.rb +1 -1
  45. data/lib/unicorn/oob_gc.rb +5 -5
  46. data/lib/unicorn/select_waiter.rb +6 -0
  47. data/lib/unicorn/socket_helper.rb +1 -0
  48. data/lib/unicorn/tmpio.rb +8 -2
  49. data/lib/unicorn/util.rb +1 -1
  50. data/lib/unicorn/version.rb +1 -1
  51. data/lib/unicorn/worker.rb +16 -2
  52. data/lib/unicorn.rb +21 -9
  53. data/man/man1/unicorn.1 +89 -88
  54. data/man/man1/unicorn_rails.1 +78 -83
  55. data/t/GNUmakefile +3 -72
  56. data/t/README +4 -4
  57. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  58. data/t/t0301.ru +13 -0
  59. data/t/test-lib.sh +2 -1
  60. data/test/benchmark/README +14 -4
  61. data/test/benchmark/ddstream.ru +50 -0
  62. data/test/benchmark/readinput.ru +40 -0
  63. data/test/benchmark/uconnect.perl +66 -0
  64. data/test/exec/test_exec.rb +14 -12
  65. data/test/test_helper.rb +38 -30
  66. data/test/unit/test_ccc.rb +4 -3
  67. data/test/unit/test_http_parser.rb +16 -0
  68. data/test/unit/test_http_parser_ng.rb +81 -0
  69. data/test/unit/test_server.rb +81 -7
  70. data/test/unit/test_signals.rb +6 -6
  71. data/test/unit/test_socket_helper.rb +1 -1
  72. data/test/unit/test_upload.rb +9 -14
  73. data/test/unit/test_util.rb +29 -3
  74. data/test/unit/test_waiter.rb +34 -0
  75. data/unicorn.gemspec +8 -7
  76. metadata +19 -13
  77. data/Documentation/GNUmakefile +0 -30
  78. data/Documentation/unicorn.1.txt +0 -187
  79. data/Documentation/unicorn_rails.1.txt +0 -175
  80. data/t/hijack.ru +0 -55
  81. data/t/t0200-rack-hijack.sh +0 -51
@@ -1,187 +0,0 @@
1
- % UNICORN(1) Unicorn User Manual
2
- % The Unicorn Community <unicorn-public@bogomips.org>
3
- % September 15, 2009
4
-
5
- # NAME
6
-
7
- unicorn - a rackup-like command to launch the Unicorn HTTP server
8
-
9
- # SYNOPSIS
10
-
11
- unicorn [-c CONFIG_FILE] [-E RACK_ENV] [-D] [RACKUP_FILE]
12
-
13
- # DESCRIPTION
14
-
15
- A rackup(1)-like command to launch Rack applications using Unicorn.
16
- It is expected to be started in your application root (APP_ROOT),
17
- but the "working_directory" directive may be used in the CONFIG_FILE.
18
-
19
- While unicorn takes a myriad of command-line options for
20
- compatibility with ruby(1) and rackup(1), it is recommended to stick
21
- to the few command-line options specified in the SYNOPSIS and use
22
- the CONFIG_FILE as much as possible.
23
-
24
- # RACKUP FILE
25
-
26
- This defaults to \"config.ru\" in APP_ROOT. It should be the same
27
- file used by rackup(1) and other Rack launchers, it uses the
28
- *Rack::Builder* DSL.
29
-
30
- Embedded command-line options are mostly parsed for compatibility
31
- with rackup(1) but strongly discouraged.
32
-
33
- # UNICORN OPTIONS
34
- -c, \--config-file CONFIG_FILE
35
- : Path to the Unicorn-specific config file. The config file is
36
- implemented as a Ruby DSL, so Ruby code may executed.
37
- See the RDoc/ri for the *Unicorn::Configurator* class for the full
38
- list of directives available from the DSL.
39
- Using an absolute path for for CONFIG_FILE is recommended as it
40
- makes multiple instances of Unicorn easily distinguishable when
41
- viewing ps(1) output.
42
-
43
- -D, \--daemonize
44
- : Run daemonized in the background. The process is detached from
45
- the controlling terminal and stdin is redirected to "/dev/null".
46
- Unlike many common UNIX daemons, we do not chdir to \"/\"
47
- upon daemonization to allow more control over the startup/upgrade
48
- process.
49
- Unless specified in the CONFIG_FILE, stderr and stdout will
50
- also be redirected to "/dev/null".
51
-
52
- -E, \--env RACK_ENV
53
- : Run under the given RACK_ENV. See the RACK ENVIRONMENT section
54
- for more details.
55
-
56
- -l, \--listen ADDRESS
57
- : Listens on a given ADDRESS. ADDRESS may be in the form of
58
- HOST:PORT or PATH, HOST:PORT is taken to mean a TCP socket
59
- and PATH is meant to be a path to a UNIX domain socket.
60
- Defaults to "0.0.0.0:8080" (all addresses on TCP port 8080)
61
- For production deployments, specifying the "listen" directive in
62
- CONFIG_FILE is recommended as it allows fine-tuning of socket
63
- options.
64
- -N, \--no-default-middleware
65
- : Disables loading middleware implied by RACK_ENV. This bypasses the
66
- configuration documented in the RACK ENVIRONMENT section, but still
67
- allows RACK_ENV to be used for application/framework-specific purposes.
68
-
69
- # RACKUP COMPATIBILITY OPTIONS
70
- -o, \--host HOST
71
- : Listen on a TCP socket belonging to HOST, default is
72
- "0.0.0.0" (all addresses).
73
- If specified multiple times on the command-line, only the
74
- last-specified value takes effect.
75
- This option only exists for compatibility with the rackup(1) command,
76
- use of "-l"/"\--listen" switch is recommended instead.
77
-
78
- -p, \--port PORT
79
- : Listen on the specified TCP PORT, default is 8080.
80
- If specified multiple times on the command-line, only the last-specified
81
- value takes effect.
82
- This option only exists for compatibility with the rackup(1) command,
83
- use of "-l"/"\--listen" switch is recommended instead.
84
-
85
- -s, \--server SERVER
86
- : No-op, this exists only for compatibility with rackup(1).
87
-
88
- # RUBY OPTIONS
89
- -e, \--eval LINE
90
- : Evaluate a LINE of Ruby code. This evaluation happens
91
- immediately as the command-line is being parsed.
92
-
93
- -d, \--debug
94
- : Turn on debug mode, the $DEBUG variable is set to true.
95
-
96
- -w, \--warn
97
- : Turn on verbose warnings, the $VERBOSE variable is set to true.
98
-
99
- -I, \--include PATH
100
- : specify $LOAD_PATH. PATH will be prepended to $LOAD_PATH.
101
- The \':\' character may be used to delimit multiple directories.
102
- This directive may be used more than once. Modifications to
103
- $LOAD_PATH take place immediately and in the order they were
104
- specified on the command-line.
105
-
106
- -r, \--require LIBRARY
107
- : require a specified LIBRARY before executing the application. The
108
- \"require\" statement will be executed immediately and in the order
109
- they were specified on the command-line.
110
-
111
- # SIGNALS
112
-
113
- The following UNIX signals may be sent to the master process:
114
-
115
- * HUP - reload config file, app, and gracefully restart all workers
116
- * INT/TERM - quick shutdown, kills all workers immediately
117
- * QUIT - graceful shutdown, waits for workers to finish their
118
- current request before finishing.
119
- * USR1 - reopen all logs owned by the master and all workers
120
- See Unicorn::Util.reopen_logs for what is considered a log.
121
- * USR2 - reexecute the running binary. A separate QUIT
122
- should be sent to the original process once the child is verified to
123
- be up and running.
124
- * WINCH - gracefully stops workers but keep the master running.
125
- This will only work for daemonized processes.
126
- * TTIN - increment the number of worker processes by one
127
- * TTOU - decrement the number of worker processes by one
128
-
129
- See the [SIGNALS][4] document for full description of all signals
130
- used by Unicorn.
131
-
132
- # RACK ENVIRONMENT
133
-
134
- Accepted values of RACK_ENV and the middleware they automatically load
135
- (outside of RACKUP_FILE) are exactly as those in rackup(1):
136
-
137
- * development - loads Rack::CommonLogger, Rack::ShowExceptions, and
138
- Rack::Lint middleware
139
- * deployment - loads Rack::CommonLogger middleware
140
- * none - loads no middleware at all, relying
141
- entirely on RACKUP_FILE
142
-
143
- All unrecognized values for RACK_ENV are assumed to be
144
- "none". Production deployments are strongly encouraged to use
145
- "deployment" or "none" for maximum performance.
146
-
147
- As of Unicorn 0.94.0, RACK_ENV is exported as a process-wide environment
148
- variable as well. While not current a part of the Rack specification as
149
- of Rack 1.0.1, this has become a de facto standard in the Rack world.
150
-
151
- Note the Rack::ContentLength and Rack::Chunked middlewares are also
152
- loaded by "deployment" and "development", but no other values of
153
- RACK_ENV. If needed, they must be individually specified in the
154
- RACKUP_FILE, some frameworks do not require them.
155
-
156
- # ENVIRONMENT VARIABLES
157
-
158
- The RACK_ENV variable is set by the aforementioned \-E switch.
159
- All application or library-specific environment variables (e.g. TMPDIR)
160
- may always be set in the Unicorn CONFIG_FILE in addition to the spawning
161
- shell. When transparently upgrading Unicorn, all environment variables
162
- set in the old master process are inherited by the new master process.
163
- Unicorn only uses (and will overwrite) the UNICORN_FD environment
164
- variable internally when doing transparent upgrades.
165
-
166
- UNICORN_FD is a comma-delimited list of one or more file descriptors
167
- used to implement USR2 upgrades. Init systems may bind listen sockets
168
- itself and spawn unicorn with UNICORN_FD set to the file descriptor
169
- numbers of the listen socket(s).
170
-
171
- As of unicorn 5.0, LISTEN_PID and LISTEN_FDS are used for socket
172
- activation as documented in the sd_listen_fds(3) manpage. Users
173
- relying on this feature do not need to specify a listen socket in
174
- the unicorn config file.
175
-
176
- # SEE ALSO
177
-
178
- * *Rack::Builder* ri/RDoc
179
- * *Unicorn::Configurator* ri/RDoc
180
- * [Unicorn RDoc][1]
181
- * [Rack RDoc][2]
182
- * [Rackup HowTo][3]
183
-
184
- [1]: https://bogomips.org/unicorn/
185
- [2]: http://www.rubydoc.info/github/rack/rack/
186
- [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
187
- [4]: https://bogomips.org/unicorn/SIGNALS.html
@@ -1,175 +0,0 @@
1
- % UNICORN_RAILS(1) Unicorn User Manual
2
- % The Unicorn Community <unicorn-public@bogomips.org>
3
- % September 17, 2009
4
-
5
- # NAME
6
-
7
- unicorn_rails - unicorn launcher for Rails 1.x and 2.x users
8
-
9
- # SYNOPSIS
10
-
11
- unicorn_rails [-c CONFIG_FILE] [-E RAILS_ENV] [-D] [RACKUP_FILE]
12
-
13
- # DESCRIPTION
14
-
15
- A rackup(1)-like command to launch Rails applications using Unicorn. It
16
- is expected to be started in your Rails application root (RAILS_ROOT),
17
- but the "working_directory" directive may be used in the CONFIG_FILE.
18
-
19
- It is designed to help Rails 1.x and 2.y users transition to Rack, but
20
- it is NOT needed for Rails 3 applications. Rails 3 users are encouraged
21
- to use unicorn(1) instead of unicorn_rails(1). Users of Rails 1.x/2.y
22
- may also use unicorn(1) instead of unicorn_rails(1).
23
-
24
- The outward interface resembles rackup(1), the internals and default
25
- middleware loading is designed like the `script/server` command
26
- distributed with Rails.
27
-
28
- While Unicorn takes a myriad of command-line options for compatibility
29
- with ruby(1) and rackup(1), it is recommended to stick to the few
30
- command-line options specified in the SYNOPSIS and use the CONFIG_FILE
31
- as much as possible.
32
-
33
- # UNICORN OPTIONS
34
- -c, \--config-file CONFIG_FILE
35
- : Path to the Unicorn-specific config file. The config file is
36
- implemented as a Ruby DSL, so Ruby code may executed.
37
- See the RDoc/ri for the *Unicorn::Configurator* class for the full
38
- list of directives available from the DSL.
39
- Using an absolute path for for CONFIG_FILE is recommended as it
40
- makes multiple instances of Unicorn easily distinguishable when
41
- viewing ps(1) output.
42
-
43
- -D, \--daemonize
44
- : Run daemonized in the background. The process is detached from
45
- the controlling terminal and stdin is redirected to "/dev/null".
46
- Unlike many common UNIX daemons, we do not chdir to \"/\"
47
- upon daemonization to allow more control over the startup/upgrade
48
- process.
49
- Unless specified in the CONFIG_FILE, stderr and stdout will
50
- also be redirected to "/dev/null".
51
- Daemonization will _skip_ loading of the *Rails::Rack::LogTailer*
52
- middleware under Rails \>\= 2.3.x.
53
- By default, unicorn\_rails(1) will create a PID file in
54
- _\"RAILS\_ROOT/tmp/pids/unicorn.pid\"_. You may override this
55
- by specifying the "pid" directive to override this Unicorn config file.
56
-
57
- -E, \--env RAILS_ENV
58
- : Run under the given RAILS_ENV. This sets the RAILS_ENV environment
59
- variable. Acceptable values are exactly those you expect in your Rails
60
- application, typically "development" or "production".
61
-
62
- -l, \--listen ADDRESS
63
- : Listens on a given ADDRESS. ADDRESS may be in the form of
64
- HOST:PORT or PATH, HOST:PORT is taken to mean a TCP socket
65
- and PATH is meant to be a path to a UNIX domain socket.
66
- Defaults to "0.0.0.0:8080" (all addresses on TCP port 8080).
67
- For production deployments, specifying the "listen" directive in
68
- CONFIG_FILE is recommended as it allows fine-tuning of socket
69
- options.
70
-
71
- # RACKUP COMPATIBILITY OPTIONS
72
- -o, \--host HOST
73
- : Listen on a TCP socket belonging to HOST, default is
74
- "0.0.0.0" (all addresses).
75
- If specified multiple times on the command-line, only the
76
- last-specified value takes effect.
77
- This option only exists for compatibility with the rackup(1) command,
78
- use of "-l"/"\--listen" switch is recommended instead.
79
-
80
- -p, \--port PORT
81
- : Listen on the specified TCP PORT, default is 8080.
82
- If specified multiple times on the command-line, only the last-specified
83
- value takes effect.
84
- This option only exists for compatibility with the rackup(1) command,
85
- use of "-l"/"\--listen" switch is recommended instead.
86
-
87
- \--path PATH
88
- : Mounts the Rails application at the given PATH (instead of "/").
89
- This is equivalent to setting the RAILS_RELATIVE_URL_ROOT
90
- environment variable. This is only supported under Rails 2.3
91
- or later at the moment.
92
-
93
- # RUBY OPTIONS
94
- -e, \--eval LINE
95
- : Evaluate a LINE of Ruby code. This evaluation happens
96
- immediately as the command-line is being parsed.
97
-
98
- -d, \--debug
99
- : Turn on debug mode, the $DEBUG variable is set to true.
100
- For Rails \>\= 2.3.x, this loads the *Rails::Rack::Debugger*
101
- middleware.
102
-
103
- -w, \--warn
104
- : Turn on verbose warnings, the $VERBOSE variable is set to true.
105
-
106
- -I, \--include PATH
107
- : specify $LOAD_PATH. PATH will be prepended to $LOAD_PATH.
108
- The \':\' character may be used to delimit multiple directories.
109
- This directive may be used more than once. Modifications to
110
- $LOAD_PATH take place immediately and in the order they were
111
- specified on the command-line.
112
-
113
- -r, \--require LIBRARY
114
- : require a specified LIBRARY before executing the application. The
115
- \"require\" statement will be executed immediately and in the order
116
- they were specified on the command-line.
117
-
118
- # RACKUP FILE
119
-
120
- This defaults to \"config.ru\" in RAILS_ROOT. It should be the same
121
- file used by rackup(1) and other Rack launchers, it uses the
122
- *Rack::Builder* DSL. Unlike many other Rack applications, RACKUP_FILE
123
- is completely _optional_ for Rails, but may be used to disable some
124
- of the default middleware for performance.
125
-
126
- Embedded command-line options are mostly parsed for compatibility
127
- with rackup(1) but strongly discouraged.
128
-
129
- # ENVIRONMENT VARIABLES
130
-
131
- The RAILS_ENV variable is set by the aforementioned \-E switch. The
132
- RAILS_RELATIVE_URL_ROOT is set by the aforementioned \--path switch.
133
- Either of these variables may also be set in the shell or the Unicorn
134
- CONFIG_FILE. All application or library-specific environment variables
135
- (e.g. TMPDIR, RAILS_ASSET_ID) may always be set in the Unicorn
136
- CONFIG_FILE in addition to the spawning shell. When transparently
137
- upgrading Unicorn, all environment variables set in the old master
138
- process are inherited by the new master process. Unicorn only uses (and
139
- will overwrite) the UNICORN_FD environment variable internally when
140
- doing transparent upgrades.
141
-
142
- # SIGNALS
143
-
144
- The following UNIX signals may be sent to the master process:
145
-
146
- * HUP - reload config file, app, and gracefully restart all workers
147
- * INT/TERM - quick shutdown, kills all workers immediately
148
- * QUIT - graceful shutdown, waits for workers to finish their
149
- current request before finishing.
150
- * USR1 - reopen all logs owned by the master and all workers
151
- See Unicorn::Util.reopen_logs for what is considered a log.
152
- * USR2 - reexecute the running binary. A separate QUIT
153
- should be sent to the original process once the child is verified to
154
- be up and running.
155
- * WINCH - gracefully stops workers but keep the master running.
156
- This will only work for daemonized processes.
157
- * TTIN - increment the number of worker processes by one
158
- * TTOU - decrement the number of worker processes by one
159
-
160
- See the [SIGNALS][4] document for full description of all signals
161
- used by Unicorn.
162
-
163
- # SEE ALSO
164
-
165
- * unicorn(1)
166
- * *Rack::Builder* ri/RDoc
167
- * *Unicorn::Configurator* ri/RDoc
168
- * [Unicorn RDoc][1]
169
- * [Rack RDoc][2]
170
- * [Rackup HowTo][3]
171
-
172
- [1]: https://bogomips.org/unicorn/
173
- [2]: http://www.rubydoc.info/github/rack/rack/
174
- [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
175
- [4]: https://bogomips.org/unicorn/SIGNALS.html
data/t/hijack.ru DELETED
@@ -1,55 +0,0 @@
1
- use Rack::Lint
2
- use Rack::ContentLength
3
- use Rack::ContentType, "text/plain"
4
- class DieIfUsed
5
- @@n = 0
6
- def each
7
- abort "body.each called after response hijack\n"
8
- end
9
-
10
- def close
11
- warn "closed DieIfUsed #{@@n += 1}\n"
12
- end
13
- end
14
-
15
- envs = []
16
-
17
- run lambda { |env|
18
- case env["PATH_INFO"]
19
- when "/hijack_req"
20
- if env["rack.hijack?"]
21
- io = env["rack.hijack"].call
22
- envs << env
23
- if io.respond_to?(:read_nonblock) &&
24
- env["rack.hijack_io"].respond_to?(:read_nonblock)
25
-
26
- # exercise both, since we Rack::Lint may use different objects
27
- env["rack.hijack_io"].write("HTTP/1.0 200 OK\r\n\r\n")
28
- io.write("request.hijacked")
29
- io.close
30
- return [ 500, {}, DieIfUsed.new ]
31
- end
32
- end
33
- [ 500, {}, [ "hijack BAD\n" ] ]
34
- when "/hijack_res"
35
- r = "response.hijacked"
36
- [ 200,
37
- {
38
- "Content-Length" => r.bytesize.to_s,
39
- "rack.hijack" => proc do |io|
40
- envs << env
41
- io.write(r)
42
- io.close
43
- end
44
- },
45
- DieIfUsed.new
46
- ]
47
- when "/normal_env_id"
48
- b = "#{env.object_id}\n"
49
- h = {
50
- 'Content-Type' => 'text/plain',
51
- 'Content-Length' => b.bytesize.to_s,
52
- }
53
- [ 200, h, [ b ] ]
54
- end
55
- }
@@ -1,51 +0,0 @@
1
- #!/bin/sh
2
- . ./test-lib.sh
3
- t_plan 9 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))"
4
-
5
- t_begin "setup and start" && {
6
- unicorn_setup
7
- unicorn -D -c $unicorn_config hijack.ru
8
- unicorn_wait_start
9
- }
10
-
11
- t_begin "normal env reused between requests" && {
12
- env_a="$(curl -sSf http://$listen/normal_env_id)"
13
- b="$(curl -sSf http://$listen/normal_env_id)"
14
- test x"$env_a" = x"$b"
15
- }
16
-
17
- t_begin "check request hijack" && {
18
- test "xrequest.hijacked" = x"$(curl -sSfv http://$listen/hijack_req)"
19
- }
20
-
21
- t_begin "env changed after request hijack" && {
22
- env_b="$(curl -sSf http://$listen/normal_env_id)"
23
- test x"$env_a" != x"$env_b"
24
- }
25
-
26
- t_begin "check response hijack" && {
27
- test "xresponse.hijacked" = x"$(curl -sSfv http://$listen/hijack_res)"
28
- }
29
-
30
- t_begin "env changed after response hijack" && {
31
- env_c="$(curl -sSf http://$listen/normal_env_id)"
32
- test x"$env_b" != x"$env_c"
33
- }
34
-
35
- t_begin "env continues to be reused between requests" && {
36
- b="$(curl -sSf http://$listen/normal_env_id)"
37
- test x"$env_c" = x"$b"
38
- }
39
-
40
- t_begin "killing succeeds after hijack" && {
41
- kill $unicorn_pid
42
- }
43
-
44
- t_begin "check stderr for hijacked body close" && {
45
- check_stderr
46
- grep 'closed DieIfUsed 1\>' $r_err
47
- grep 'closed DieIfUsed 2\>' $r_err
48
- ! grep 'closed DieIfUsed 3\>' $r_err
49
- }
50
-
51
- t_done