Compare commits

...
168 Commits
Author SHA1 Message Date
roberto@gambit b361248ff6 fixed add_exported_opts 2011-10-23 08:35:15 +02:00
roberto@debian32 e9c42ceaa5 support for multiple values in options 2011-10-22 18:32:32 +02:00
roberto@debian32 5d7029744a PATH_INFO is correctly escaped in http modes 2011-10-22 09:35:01 +02:00
roberto@gambit 1084a3afa8 fixed mule patch loading 2011-10-20 10:38:59 +02:00
roberto@gambit ed254bffee fixed mule process name 2011-10-20 10:20:44 +02:00
roberto@djangocloud 733784d7dd another procname fix... 2011-10-19 16:13:10 +10:00
roberto@djangocloud cb5b26bcb4 another bunch of procname fixes 2011-10-19 14:26:07 +10:00
roberto@djangocloud 0065152bb1 daemons throttling subsystem 2011-10-18 18:53:22 +10:00
roberto@djangocloud 03266203fd another fix for environ 2011-10-18 18:30:13 +10:00
roberto@djangocloud 4a5f68f9d8 fixed environ 2011-10-18 18:12:39 +10:00
roberto@djangocloud 83e31a1c27 another setprocname fix 2011-10-18 16:20:33 +10:00
roberto@djangocloud 0efed5ef9c various emperor procname fixes 2011-10-18 16:15:06 +10:00
roberto@djangocloud cdfef1281d fixed another spooler compilation bug 2011-10-18 15:12:59 +10:00
roberto@debian32 e00907e142 --spooler-harakiri 2011-10-17 19:07:12 +02:00
roberto@app1 6dcbcf39e3 fixed compilation when spooler is disabled 2011-10-17 03:16:55 -05:00
roberto@debian32 044579a8e0 more verbose annihilation report 2011-10-16 11:16:13 +02:00
roberto@debian32 d2b52b4663 added uwsgi.setprocname() 2011-10-16 10:37:26 +02:00
roberto@debian32 7f75b2c02c added --procname and --procname-master 2011-10-16 10:18:45 +02:00
roberto@freebsd64 24a3f671e5 freebsd setproctitle 2011-10-16 10:06:08 +02:00
roberto@debian32 875100e3c8 check for mules before nuke 2011-10-16 09:58:37 +02:00
roberto@mrspurr 34bc7c0cfd check for procname 2011-10-16 09:54:35 +02:00
roberto@debian32 b39a10ff7c procname initial management 2011-10-16 09:45:41 +02:00
roberto@debian32 02331904de uWSGI 1.0-rc1 2011-10-15 08:47:00 +02:00
roberto@debian32 d1a4ae694e --locks 2011-10-15 08:32:32 +02:00
roberto@debian32 7a5ffc1124 --spooler-chdir 2011-10-14 19:20:05 +02:00
roberto@debian32 19c5bfb42c fixed a spooler signal bug spotted by Gabriele Giaccari 2011-10-14 18:32:17 +02:00
roberto@debian32 893bf3686b fixed a wrong typecast 2011-10-14 10:58:02 +02:00
roberto@debian32 e54fa9bcd4 added --emperor-stats 2011-10-13 07:53:32 +02:00
roberto@debian32 c1eb5ab0fe prepare for emperor-stats 2011-10-12 06:51:49 +02:00
roberto@mrspurr 461914dde4 completed --evil-reload options 2011-10-12 06:48:52 +02:00
roberto@debian32 85662578e4 implemented --mule-harakiri 2011-10-12 01:48:30 +02:00
roberto@debian32 a59c0ae795 setlinebuf in syslog mode 2011-10-12 00:54:18 +02:00
roberto@debian32 3a860155ee added --evil-reload-on-as and --evil-reload-on-rss 2011-10-11 20:39:00 +02:00
roberto@debian32 27553c2967 prepare for --evil-reload-... options 2011-10-11 20:18:31 +02:00
roberto@colossus 9a8ac9af3c added uwsgi.mule_id() 2011-10-11 07:31:41 +02:00
roberto@debian32 2f5daffe99 use hggit for better github sync 2011-10-09 09:11:54 +02:00
roberto@debian32 75cd31dce4 better spooler error reporting 2011-10-07 03:30:16 +02:00
roberto@colossus f7150d1b41 fixed mule socketpair 2011-10-06 18:37:24 +02:00
roberto@debian32 d6a6b65338 added --log-x-forwarded-for 2011-10-06 06:42:31 +02:00
roberto@freebsd64 979f6027b4 ignore SIGPIPE by default 2011-10-05 20:45:55 +02:00
roberto@freebsd64 7dc059c75b completed new freebsd64 sendfiel async support 2011-10-05 20:34:25 +02:00
roberto@freebsd64 b639b5974f better freebsd sendfile support 2011-10-05 20:19:12 +02:00
roberto@netbsd64 0de08c553c fixed a potential overflow 2011-10-05 21:16:28 +02:00
roberto@freebsd64 80788ac695 freebsd event fix 2011-10-05 19:01:29 +02:00
roberto@freebsd64 1494c621c1 non-linux fix 2011-10-05 18:43:53 +02:00
roberto@debian32 605e5b5173 export listen_queue size in stats 2011-10-05 17:24:46 +02:00
roberto@debian32 4cf2213051 added --log-truncate --log-reopen --log-maxsize --log-backupname 2011-10-05 11:58:15 +02:00
roberto@debian32 3aa36668e5 better error reporting 2011-10-04 20:28:08 +02:00
roberto@debian32 1c0b5b42e9 support for multiple --touch-reload options 2011-10-04 19:40:09 +02:00
roberto@openindiana64 702dc44fad fixed openindiana build on 64bit 2011-10-03 15:46:04 +02:00
roberto@solrisexpress 2cae07aa52 fixed 64bit compilation 2011-10-03 09:37:32 +00:00
roberto@ebian32 b5616ff25c completed mule signal handling 2011-10-03 08:36:21 +02:00
roberto@debian32 b7b7521975 refactored fds closing and socketpair 2011-10-03 08:29:19 +02:00
roberto@debian32 dce3263ee3 added mule messaging subsystem 2011-10-03 07:45:18 +02:00
roberto@debian32 9796e05ca1 added support for X_FORWARDED_SSL in http parser 2011-10-03 06:38:14 +02:00
roberto@debian32 5cc0d459ec struct uwsgi_server is becoming huge, better to add some comment 2011-10-02 20:45:03 +02:00
roberto@debian32 531a850a71 first almost-working commit for uWSGI mules 2011-10-02 20:05:31 +02:00
roberto@debian32 4c36280287 support --manage-script-name in http socket mode 2011-09-30 12:32:31 +02:00
roberto@debian32 70be8eb55e restored setup.py 2011-09-30 10:55:12 +02:00
roberto@debian32 f8b757b21e print argv in setup.py 2011-09-30 10:39:22 +02:00
roberto@debian32 3a63d352bb print envs in setup.py 2011-09-30 10:36:30 +02:00
roberto@sirius 60467705c5 fixed a stupid bug 2011-09-30 10:31:00 +02:00
roberto@debian32 eada0c09e0 refactored placeholder management 2011-09-30 10:21:26 +02:00
roberto@debian32 8e851aa6a1 fixed egg 2011-09-30 09:56:51 +02:00
roberto@debian32 eaf7bb967d added a check for http (3) 2011-09-30 09:43:42 +02:00
roberto@debian32 7be45c77b1 added a check for http (2) 2011-09-30 09:42:19 +02:00
roberto@debian32 5e2b460dc8 added a check for http (2) 2011-09-30 09:24:33 +02:00
roberto@debian32 16143e698f added a check for http 2011-09-30 09:21:12 +02:00
roberto@debian32 4259946e3b second little typecast fix 2011-09-30 08:51:18 +02:00
roberto@debian32 0a750d76ee little typecast fix 2011-09-30 08:50:00 +02:00
roberto@debian32 e4a9f5f0dd merge 2011-09-28 20:21:11 +02:00
roberto@debian32 d5b7698f89 added --stats 2011-09-28 20:20:40 +02:00
roberto@sirius a481e8508e added .gitignore 2011-09-28 17:23:22 +02:00
roberto@debian32 a53b57497b close bug #47 2011-09-28 07:27:43 +02:00
roberto@debian32 d871357b2d added uwsgi_req_error 2011-09-25 16:16:08 +02:00
roberto@debian32 2d57db55f4 removed a useless error checking 2011-09-25 14:06:06 +02:00
roberto@debian32 bae45ce03a error checking in uwsgi proto writer 2011-09-25 14:01:06 +02:00
roberto@debian32 44cc4336f1 added posix capability support 2011-09-25 13:41:10 +02:00
roberto@debian32 44f6e214fd improved uwsgi.queue_last 2011-09-25 10:44:19 +02:00
roberto@debian32 3e46f81d2b use PyLong_FromUnsignedLongLong 2011-09-25 06:42:23 +02:00
roberto@debian32 e4532b9a50 added memory usage in uwsgicc 2011-09-24 09:07:34 +02:00
roberto@debian32 2694be562c fixed respawn_count 2011-09-24 08:28:19 +02:00
roberto@debian32 fadb9edd7f added running time and avg_rt to uwsgicc 2011-09-24 08:24:51 +02:00
roberto@debian32 d85e0790de added response_time and running_time statistics 2011-09-24 06:40:30 +02:00
roberto@debian32 bc46c4d704 python3 fix 2011-09-23 08:36:28 +02:00
roberto@centos64 a73a010188 fixed build system for older gcc releases 2011-09-23 08:33:15 +02:00
roberto@debian3 4e8c8ef317 improved screen support 2011-09-21 06:09:05 +02:00
roberto@debian32 e402e7805d no need to set pty, screen is much metter 2011-09-21 05:27:58 +02:00
roberto@debian32 302b8f026b --cheaper improvement 2011-09-19 10:15:24 +02:00
roberto@debian32 630054b72a better wakeup of workers 2011-09-19 07:53:51 +02:00
roberto@debian32 a05f459b2b preliminary cheaper implementation 2011-09-19 07:13:45 +02:00
roberto@debian32 207979580a added uwsgi.extract 2011-09-18 07:04:36 +02:00
roberto@debian32 f69526f8bf parse plugin-specific options 2011-09-18 06:57:19 +02:00
roberto@debian32 e249d567a1 --fastrouter-cheap 2011-09-16 15:14:08 +02:00
roberto@debian32 a23ba653da better shared sockets support 2011-09-16 07:46:45 +02:00
roberto@debian32 0644d53572 set pty to raw mode 2011-09-13 08:35:50 +02:00
roberto@debian32 f58f51294d fixed sendfile typecasting 2011-09-11 07:41:42 +02:00
roberto@debian32 86194eb93e GC in symzipimporter is useless 2011-09-11 07:33:23 +02:00
roberto@debian32 0a89f375e6 added charles as contributor 2011-09-11 06:55:27 +02:00
roberto@debian32 6282178b3c fixed python optimize flag 2011-09-11 06:42:45 +02:00
roberto@debian32 8e14d68022 merge 2011-09-10 17:28:40 +02:00
roberto@debian32 e86bd0c070 preliminary support for detachable pyshell 2011-09-10 17:28:01 +02:00
roberto@mrspurr bf991f8892 report gb objects in welcome.py 2011-09-10 11:03:39 +02:00
roberto@mrspurr b341678d20 another symzip fix 2011-09-10 10:58:37 +02:00
roberto@mrspurr 5f59365d88 symzip GC fix 2011-09-10 10:54:27 +02:00
roberto@debian32 5130a7bb33 moved the old 'j' to 'J' option 2011-09-09 20:36:00 +02:00
roberto@dexter cc84a596d6 better iso99 check 2011-09-09 18:44:18 +02:00
roberto@longshot e67bed431a a fix for older gcc 2011-09-09 18:43:08 +02:00
roberto@dexter 72613a9f48 mime type optimization 2011-09-09 18:35:29 +02:00
roberto@sirius c048ea0615 better mimetype file check 2011-09-09 18:14:53 +02:00
roberto@dexter 957ca1b7ed added mime types support in static file serving 2011-09-09 17:06:35 +02:00
roberto@ebian32 d80a6df039 fixed a threading bug 2011-09-09 10:00:09 +02:00
roberto@mrspurr 94f9bd9d91 added Corey as contributor 2011-09-09 08:53:37 +02:00
roberto@mrspurr b480efe672 fixed script_name handling 2011-09-09 08:42:31 +02:00
roberto@mrspurr 4fc306d979 added a new debug entry 2011-09-09 08:32:20 +02:00
roberto@mrspurr 56abccbdeb another fix for urack.rb 2011-09-08 19:59:37 +02:00
roberto@mrspuur f218af0735 clang fixes 2011-09-08 19:45:46 +02:00
roberto@mrspurr 9b69c62780 automagic bundler in urack.rb 2011-09-08 13:44:50 +02:00
roberto@dexter eb5d67e07f 1.0 is better than 1.0.0 2011-09-07 16:09:45 +02:00
roberto@sirius e7391987b1 fixed sandboxviolation on osx 2011-09-07 12:33:12 +02:00
roberto@sirius 02cbe15575 test3 2011-09-07 12:32:02 +02:00
roberto@sirius a5a657f0d4 a second test 2011-09-07 12:29:24 +02:00
roberto@sirius 67567c86e0 a test 2011-09-07 12:27:47 +02:00
roberto@dexter 445d02da45 make easy_install happy 2011-09-06 17:58:02 +02:00
roberto@debian32 4a05df41ce subscription logging 2011-09-05 16:26:25 +02:00
roberto@debian32 5c0c2f6b45 yaml fix 2011-09-05 08:12:12 +02:00
roberto@debian32 0ab55fef46 added support for regexp in UWSGI_APPID 2011-09-04 21:33:30 +02:00
roberto@debian32 dd344bfe38 fixed a bug in multiapp mode 2011-09-04 18:01:04 +02:00
roberto@debian32 e92a889bcc refactored UWSGI_PY_READLINE_BUFSIZE 2011-09-03 07:15:51 +02:00
roberto@debian32 419d656a83 1.0.0-dev cycle started 2011-08-31 14:27:21 +02:00
roberto@debian32 3c3d58bfe9 pypyuwsgi.py 2011-08-31 14:01:46 +02:00
roberto@debian32 1989099cc5 preliminary pypy support 2011-08-31 13:18:32 +02:00
roberto@sirius 1446e3f0a9 allows pyuwsgi in osx 2011-08-31 12:09:56 +02:00
roberto@debian32 00fc31289d a pyuwsgi fix 2011-08-31 12:06:26 +02:00
roberto@sirius 2c463ad6af a test for libless pyuwsgi 2011-08-31 12:02:19 +02:00
roberto@sirius e641ae05c4 pyuwsgi 2011-08-31 11:42:22 +02:00
roberto@debian32 a13e0075ee fixed virtualhosting in fully-dynamic mode 2011-08-31 07:55:34 +02:00
roberto@debian32 e617a7b88e added an example for the new fd-based config 2011-08-30 12:08:22 +02:00
roberto@debian32 cbdeb4caad --stop and --reload, open by fifo and fd 2011-08-30 10:51:50 +02:00
roberto@sirius 59314d692f uWSGI 0.9.9 2011-08-29 17:32:08 +02:00
roberto@sirius 3dfa56b279 Added tag 0.9.9 for changeset 376ffd8f1906 2011-08-29 17:26:31 +02:00
roberto@dexter 920d5d7416 Changelog for 0.9.9 2011-08-29 11:32:27 +02:00
roberto@dexter dcb654d7fb spooler reload fix 2011-08-29 10:50:09 +02:00
roberto@solarisexpress a563da1223 solaris fix for lockf() 2011-08-29 10:34:46 +00:00
roberto@sirius 1e26cda615 fixed a race condition 2011-08-29 10:30:01 +02:00
roberto@dexter 97133b27ce the decoratortest is fully working, ready for release 2011-08-29 09:54:07 +02:00
roberto@sirius b428bd3b87 another bunch of build fixes 2011-08-29 08:02:37 +02:00
roberto@dexter 05136e74b4 fixed build system 2011-08-29 07:55:46 +02:00
roberto@mrspurr 9f28a8bdf1 improved upload progress 2011-08-28 20:53:46 +02:00
roberta@mrspurr d9361f1fee added test for upload progress 2011-08-28 19:13:56 +02:00
roberto@debian32 835230b1a4 emperor-tyrant 2011-08-28 09:15:13 +02:00
roberto@debian32 f88f51c553 added welcome.ini 2011-08-28 08:33:49 +02:00
roberto@debian32 1996305eb1 allows multiple --ini options 2011-08-28 07:55:54 +02:00
roberto@solrisexpress c7ad50e950 do not free getexecname() ret value 2011-08-28 07:37:21 +00:00
roberto@debian32 0ec0c29d67 fixed an indentation 2011-08-28 07:21:49 +02:00
roberto@solarisexpress 75af117e8a better magic plugin loading on binary_path 2011-08-28 07:14:42 +00:00
roberto@debian32 2b04cefe4e added help for a bunch of options 2011-08-27 19:37:34 +02:00
roberto@debian32 0e41c4111a fixed upstart 2011-08-27 18:46:53 +02:00
roberto@debian32 5f5d382c64 signal framework ported to gevent 2011-08-27 07:15:44 +02:00
roberto@dexter 3e867fe401 resolve domain names in socket logging 2011-08-26 16:20:14 +02:00
roberto@dexter 153142b8b0 fixed django uwsgi_admin without spooler 2011-08-26 15:02:02 +02:00
roberto@dexter 5562c0c047 use hub.join() instead of hub.switch() 2011-08-26 14:05:03 +02:00
roberto@debian32 f4a1f800ba timeout handling in gevent plugin 2011-08-26 12:34:12 +02:00
roberto@debian32 bdbc5e5605 another gevent improvement suggested by denis 2011-08-26 11:35:32 +02:00
roberto@debian32 4104f825ff another improvement for sys.executable in python3 2011-08-26 10:28:34 +02:00
roberto@longshot efa01ea404 better sys.executable and sys.argv values 2011-08-26 10:08:01 +02:00
roberto@debian32 982559ae66 snmp fixes 2011-08-26 09:54:11 +02:00
roberto@gambit 60002e8de8 Added tag 0.9.9-rc2 for changeset 6aa667612019 2011-08-26 08:17:20 +02:00
70 changed files with 3937 additions and 682 deletions
+3
View File
@@ -30,3 +30,6 @@ fd8477b6348faf16588106055ca59df1c488f76a 0.9.8.1
f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
6945ee03c7ea95eb19217ef1e1fb17d9ae26adbc 0.9.9-beta1
fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
6aa667612019fcff8e68af9469f73aff6fa378a8 0.9.9-rc2
376ffd8f190623e5e2521fe9fa64bf03c31e71be 0.9.9
7048ae11cfc8453c6bb599af3c0dfacd7ebae43c 1.0-rc1
+2
View File
@@ -12,3 +12,5 @@ Marco Beri, Link I.T. S.p.a.
Leonid Borisenko
Cal Leeming, Simplicity Media Ltd
Luigi Scarso
Corey Farwell
Charles Duffy
+34
View File
@@ -1,3 +1,37 @@
*** august 2011 ***
* 0.9.9 [20110829]
- various spooler improvements
- upload progress optimizations and fixes
- new emperor mode: Tyrant
- allows multiple --ini options
- better binary path detection
- gevent loop engine support
- resolve domain names in socket logging
- snmp fixes and reintroduction of the snmp-api
- fixed grunt mode
- you can specify build profile via env var UWSGI_PROFILE
- reintroduction of string-based multiapp
- new option --emperor-throttle
- improved queue and sharedarea subsystems
- uWSGI can now be built as a shared library
- new api attribute: uwsgi.magic_table
- improved apache2 module
- new option --pyshell
- allow threads in gateways
- fastrouter improvements
- the application list is now shared and exported to the api
- allows setting the thread stack size
- UWSGI_APPID for better multiapp hosting
- better reloading in lazy mode
- native pump support
- various rack fixes
- support for attaching binary data in the executable
- new option --set
- extreme-optimized http protocol parser
- WSGI handler optimizations
*** july 2011 ***
* 0.9.8.3 [20110723]
+3
View File
@@ -0,0 +1,3 @@
import uwsgi
print uwsgi.extract("data://0")
+5
View File
@@ -0,0 +1,5 @@
[uwsgi]
inherit = default
bin_name = pyuwsgi.so
embedded_plugins = pyuwsgi,python,ping,cache,nagios,rpc,ugreen
as_shared_library = true
+8 -2
View File
@@ -138,7 +138,7 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *
struct uwsgi_subscriber *usub, nusub;
int found = 0;
int i;
ptr = uwsgi_dict_get(udict, usr->key, usr->keylen, &vallen);
if (ptr && vallen) {
usub = (struct uwsgi_subscriber *) ptr;
@@ -164,6 +164,8 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *
if (found == (int) usub->nodes) {
usub->nodes++;
}
uwsgi_log("[uwsgi-subscription] %.*s => new node: %.*s\n", usr->keylen, usr->key, usr->address_len, usr->address);
udict->count++;
}
return;
}
@@ -171,9 +173,13 @@ void uwsgi_add_subscriber(struct uwsgi_dict *udict, struct uwsgi_subscribe_req *
nusub.nodes = 1;
nusub.current = 0;
memcpy(nusub.names[0].name, usr->address, usr->address_len);
nusub.names[0].len = usr->address_len;
nusub.names[0].modifier1 = usr->modifier1;
nusub.names[0].modifier2 = usr->modifier2;
uwsgi_dict_set(udict, usr->key, usr->keylen, (char *) &nusub, sizeof(struct uwsgi_subscriber));
uwsgi_log("[uwsgi-subscription] new pool: %.*s\n", usr->keylen, usr->key);
uwsgi_log("[uwsgi-subscription] %.*s => new node: %.*s\n", usr->keylen, usr->key, usr->address_len, usr->address);
udict->count++;
}
}
@@ -512,7 +518,7 @@ int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint
uci->prev = last_index;
}
}
else if (flags && UWSGI_CACHE_FLAG_UPDATE) {
else if (flags & UWSGI_CACHE_FLAG_UPDATE) {
uci = &uwsgi.cache_items[index] ;
if (expires) {
expires += time(NULL);
+3 -1
View File
@@ -12,4 +12,6 @@ env LOGTO=/tmp/uwsgi.log
env BINPATH=/home/foo/uwsgi/uwsgi
# --no-orphans avoid workers without master
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -m simple_app --logto $LOGTO -M -p 4
# --die-on-term could be a good idea
exec $BINPATH --no-orphans --socket :3033 --uid 1001 --gid 1001 --limit-as 256 -w simple_app --logto $LOGTO -M -p 4
+4
View File
@@ -1,5 +1,9 @@
require 'rubygems'
require 'socket'
begin
require 'bundler/setup'
rescue LoadError
end
require 'rack'
require 'rack/content_length'
require 'rack/rewindable_input'
+2
View File
@@ -0,0 +1,2 @@
[uwsgi]
show-config = true
+21 -10
View File
@@ -10,8 +10,8 @@ import time
# register rpc function helloworld
@rpc("helloworld")
def hello_world():
return "Hello World"
def hello2():
return "[RPC] Hello World"
# register signal 1
@signal(1)
@@ -45,6 +45,7 @@ def tmpmodified(num):
def a_long_task(args):
for i in xrange(1,10):
print("%s = %d" % ( str(args), i))
print(uwsgi.call('helloworld'))
time.sleep(1)
# continuosly spool a long running task
@@ -52,10 +53,12 @@ def a_long_task(args):
def an_infinite_task(args):
for i in xrange(1,4):
print("infinite: %d %s" % (i, str(args)))
print(uwsgi.call('helloworld'))
uwsgi.signal(100)
time.sleep(1)
# spool a task after 60 seconds
# spool a task after 5 seconds
@spool
def delayed_task(args):
print("*** I am a delayed spool job. It is %s [%s]***" % (time.asctime(), str(args)))
@@ -89,7 +92,10 @@ def a_running_thread_with_args(who):
def a_post_fork_thread():
while True:
time.sleep(3)
print("Hello from a thread in worker %d" % uwsgi.worker_id())
if uwsgi.i_am_the_spooler():
print("Hello from a thread in the spooler")
else:
print("Hello from a thread in worker %d" % uwsgi.worker_id())
@postfork
def fork_happened():
@@ -97,24 +103,29 @@ def fork_happened():
@postfork
def fork_happened2():
print("waiting for a signal...")
uwsgi.signal_wait()
print("signal received: %d" % uwsgi.signal_received())
if uwsgi.i_am_the_spooler():
return
print("worker %d is waiting for signal 100..." % uwsgi.worker_id())
uwsgi.signal_wait(100)
print("worker %d received signal %d" % (uwsgi.worker_id(), uwsgi.signal_received()))
print("fork() has been called [2] wid: %d" % uwsgi.worker_id())
@postfork
@lock
def locked_func():
print("starting locked function on worker %d" % uwsgi.worker_id())
for i in xrange(1, 100):
time.sleep(0.2)
for i in xrange(1, 5):
time.sleep(1)
print("[locked %d] waiting..." % uwsgi.worker_id())
print("done with locked function on worker %d" % uwsgi.worker_id())
print(uwsgi.call('helloworld'))
spool_filename = a_long_task.spool({'foo':'bar'}, hello='world')
print("spool filename = %s" % spool_filename)
an_infinite_task.spool(foo='bar', priority=3)
delayed_task.spool(foo2='bar2', at=time.time()+60)
when = int(time.time())+5
print("scheduling a delayed task at %d" % when)
delayed_task.spool(foo2='bar2', at=when)
a_running_thread()
a_running_thread_with_args("uWSGI")
uwsgi_source_file = open('uwsgi.c','r')
+4 -3
View File
@@ -14,10 +14,11 @@ def index(request):
w['load'] = (100 * (w['running_time']/1000))/total_load
w['last_spawn_str'] = time.ctime(w['last_spawn'])
spooler_jobs = uwsgi.spooler_jobs()
jobs = []
for j in spooler_jobs:
jobs.append({'file': j, 'env': uwsgi.parsefile(j)})
if 'spooler' in uwsgi.opt:
spooler_jobs = uwsgi.spooler_jobs()
for j in spooler_jobs:
jobs.append({'file': j, 'env': uwsgi.parsefile(j)})
return render_to_response('uwsgi.html', {'masterpid': uwsgi.masterpid(),
'started_on': time.ctime(uwsgi.started_on),
+161 -20
View File
@@ -8,6 +8,8 @@ extern char **environ;
int emperor_queue;
char *emperor_absolute_dir;
void emperor_send_stats(int);
struct uwsgi_instance {
struct uwsgi_instance *ui_prev;
struct uwsgi_instance *ui_next;
@@ -32,6 +34,9 @@ struct uwsgi_instance {
int loyal;
int zerg;
uid_t uid;
gid_t gid;
};
@@ -169,12 +174,12 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
uwsgi_log("reload the uwsgi instance %s\n", c_ui->name);
}
void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
void emperor_add(char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid) {
struct uwsgi_instance *c_ui = ui;
struct uwsgi_instance *n_ui = NULL;
pid_t pid;
char **argv;
char **vassal_argv;
char *uef;
char **uenvs;
int counter;
@@ -183,6 +188,13 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
usleep(uwsgi.emperor_throttle*1000);
if (uwsgi.emperor_tyrant) {
if (uid == 0 || gid == 0) {
uwsgi_log("[emperor-tyrant] invalid permissions for file %s\n", name);
return;
}
}
while (c_ui->ui_next) {
c_ui = c_ui->ui_next;
}
@@ -209,6 +221,8 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
memcpy(n_ui->name, name, strlen(name));
n_ui->born = born;
n_ui->uid = uid;
n_ui->gid = gid;
n_ui->last_mod = born;
// start without loyalty
n_ui->last_loyal = born;
@@ -253,6 +267,24 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
}
else {
if (uwsgi.emperor_tyrant) {
uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) uid, (int) gid, name);
if (setgid(gid)) {
uwsgi_error("setgid()");
exit(1);
}
if (setgroups(0, NULL)) {
uwsgi_error("setgroups()");
exit(1);
}
if (setuid(uid)) {
uwsgi_error("setuid()");
exit(1);
}
}
unsetenv("UWSGI_RELOADS");
unsetenv("NOTIFY_SOCKET");
@@ -308,9 +340,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
uct = uct->next;
}
argv = uwsgi_malloc(sizeof(char *) * counter);
vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
// set args
argv[0] = uwsgi.binary_path;
vassal_argv[0] = uwsgi.binary_path;
if (uwsgi.emperor_broodlord) {
colon = strchr(name, ':');
@@ -319,29 +351,29 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
}
}
if (!strcmp(name + (strlen(name) - 4), ".xml"))
argv[1] = "--xml";
vassal_argv[1] = "--xml";
if (!strcmp(name + (strlen(name) - 4), ".ini"))
argv[1] = "--ini";
vassal_argv[1] = "--ini";
if (!strcmp(name + (strlen(name) - 4), ".yml"))
argv[1] = "--yaml";
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 5), ".yaml"))
argv[1] = "--yaml";
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 3), ".js"))
argv[1] = "--json";
vassal_argv[1] = "--json";
if (colon) {
colon[0] = ':';
}
argv[2] = name;
vassal_argv[2] = name;
counter = 3;
uct = uwsgi.vassals_templates;
while(uct) {
argv[counter] = "--inherit";
argv[counter+1] = uct->filename;
vassal_argv[counter] = "--inherit";
vassal_argv[counter+1] = uct->filename;
counter+=2;
uct = uct->next;
}
argv[counter] = NULL;
vassal_argv[counter] = NULL;
// close all of the unneded fd
for(i=3;i<sysconf(_SC_OPEN_MAX);i++) {
@@ -360,7 +392,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size) {
}
// start !!!
if (execvp(argv[0], argv)) {
if (execvp(vassal_argv[0], vassal_argv)) {
uwsgi_error("execvp()");
}
uwsgi_log("is the uwsgi binary in your system PATH ?\n");
@@ -400,6 +432,8 @@ void emperor_loop() {
int interesting_fd;
char notification_message[64];
uwsgi.emperor_stats_fd = -1;
signal(SIGPIPE, SIG_IGN);
uwsgi_unix_signal(SIGINT, royal_death);
uwsgi_unix_signal(SIGTERM, royal_death);
@@ -420,6 +454,23 @@ void emperor_loop() {
uwsgi_log("*** starting uWSGI Emperor ***\n");
}
if (uwsgi.emperor_stats) {
char *tcp_port = strchr(uwsgi.emperor_stats, ':');
if (tcp_port) {
// disable deferred accept for this socket
int current_defer_accept = uwsgi.no_defer_accept;
uwsgi.no_defer_accept = 1;
uwsgi.emperor_stats_fd = bind_to_tcp(uwsgi.emperor_stats, uwsgi.listen_queue, tcp_port);
uwsgi.no_defer_accept = current_defer_accept;
}
else {
uwsgi.emperor_stats_fd = bind_to_unix(uwsgi.emperor_stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
event_queue_add_fd_read(emperor_queue, uwsgi.emperor_stats_fd);
uwsgi_log("*** Emperor stats server enabled on %s fd: %d ***\n", uwsgi.emperor_stats, uwsgi.emperor_stats_fd);
}
amqp_port = strchr(uwsgi.emperor_dir, ':');
if (amqp_port) {
@@ -517,7 +568,7 @@ reconnect:
}
else {
if (msgsize > 0) {
emperor_add(config_file, time(NULL), config, msgsize);
emperor_add(config_file, time(NULL), config, msgsize, 0, 0);
}
}
@@ -554,13 +605,18 @@ reconnect:
emperor_respawn(ui_current, time(NULL));
}
else {
emperor_add(config_file, time(NULL), NULL, 0);
emperor_add(config_file, time(NULL), NULL, 0, 0, 0);
}
free(config_file);
}
}
}
else if (uwsgi.emperor_stats && uwsgi.emperor_stats_fd > -1) {
if (interesting_fd == uwsgi.emperor_stats_fd) {
emperor_send_stats(uwsgi.emperor_stats_fd);
}
}
else {
ui_current = emperor_get_by_fd(interesting_fd);
if (ui_current) {
@@ -583,7 +639,7 @@ reconnect:
else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
uwsgi_log("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
char *zerg_name = uwsgi_concat3(ui_current->name,":","zerg");
emperor_add(zerg_name, time(NULL), NULL, 0);
emperor_add(zerg_name, time(NULL), NULL, 0, ui_current->uid, ui_current->gid);
free(zerg_name);
}
}
@@ -620,13 +676,21 @@ reconnect:
ui_current = emperor_get(de->d_name);
if (ui_current) {
// check if uid or gid are changed, in such case, sotp the instance
if (uwsgi.emperor_tyrant) {
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n");
emperor_stop(ui_current);
continue;
}
}
// check if mtime is changed and the uWSGI instance must be reloaded
if (st.st_mtime > ui_current->last_mod) {
emperor_respawn(ui_current, st.st_mtime);
}
}
else {
emperor_add(de->d_name, st.st_mtime, NULL, 0);
emperor_add(de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
}
}
}
@@ -659,13 +723,21 @@ reconnect:
ui_current = emperor_get(g.gl_pathv[i]);
if (ui_current) {
// check if uid or gid are changed, in such case, sotp the instance
if (uwsgi.emperor_tyrant) {
if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) {
uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n");
emperor_stop(ui_current);
continue;
}
}
// check if mtime is changed and the uWSGI instance must be reloaded
if (st.st_mtime > ui_current->last_mod) {
emperor_respawn(ui_current, st.st_mtime);
}
}
else {
emperor_add(g.gl_pathv[i], st.st_mtime, NULL, 0);
emperor_add(g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
}
}
@@ -729,7 +801,7 @@ reconnect:
}
else {
// UNSAFE
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len);
emperor_add(ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid);
emperor_del(ui_current);
}
break;
@@ -748,3 +820,72 @@ reconnect:
}
}
#define stats_send_llu(x, y) fprintf(output, x, (long long unsigned int) y)
#define stats_send(x, y) fprintf(output, x, y)
void emperor_send_stats(int fd) {
struct sockaddr_un client_src;
socklen_t client_src_len = 0;
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
if (client_fd < 0) {
uwsgi_error("accept()");
return;
}
FILE *output = fdopen(client_fd, "w");
if (!output) {
uwsgi_error("fdopen()");
close(client_fd);
return;
}
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
char *cwd = uwsgi_get_cwd();
stats_send("\"cwd\": \"%s\",\n", cwd);
free(cwd);
stats_send("\"emperor\": \"%s\",\n", uwsgi.emperor_dir);
fprintf(output,"\"emperor_tyrant\": %d,\n", uwsgi.emperor_tyrant);
fprintf(output, "\"vassals\": [\n");
struct uwsgi_instance *c_ui = ui->ui_next;
while (c_ui) {
fprintf(output,"\t{");
stats_send("\"id\": \"%s\", ", c_ui->name);
fprintf(output,"\"pid\": %d, ", (int) c_ui->pid);
stats_send_llu( "\"born\": %llu, ", c_ui->born);
stats_send_llu( "\"last_mod\": %llu, ", c_ui->last_mod);
fprintf(output,"\"loyal\": %d, ", c_ui->loyal);
fprintf(output,"\"zerg\": %d, ", c_ui->zerg);
fprintf(output,"\"uid\": %d, ", (int)c_ui->uid);
fprintf(output,"\"gid\": %d, ", (int)c_ui->gid);
stats_send_llu( "\"respawns\": %llu ", c_ui->respawns);
c_ui = c_ui->ui_next;
if (c_ui) {
fprintf(output,"},\n");
}
else {
fprintf(output,"}\n");
}
}
fprintf(output,"]}\n");
fclose(output);
}
+15 -5
View File
@@ -81,7 +81,7 @@ void *event_queue_alloc(int nevents) {
int event_queue_interesting_fd(void *events, int id) {
port_event_t *pe = (port_event_t *) events;
if (pe[id].portev_source == PORT_SOURCE_FILE || pe[id].portev_source == PORT_SOURCE_TIMER) {
return (int) pe[id].portev_user;
return (long) pe[id].portev_user;
}
return (int) pe[id].portev_object;
@@ -149,7 +149,7 @@ int event_queue_wait(int eq, int timeout, int *interesting_fd) {
if (pe.portev_source == PORT_SOURCE_FILE || pe.portev_source == PORT_SOURCE_TIMER) {
*interesting_fd = (int) pe.portev_user;
*interesting_fd = (long) pe.portev_user;
}
else {
*interesting_fd = (int) pe.portev_object;
@@ -327,11 +327,13 @@ int event_queue_fd_write_to_read(int eq, int fd) {
struct kevent kev;
#ifndef __FreeBSD__
EV_SET(&kev, fd, EVFILT_WRITE, EV_DISABLE, 0, 0, 0);
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
uwsgi_error("kevent()");
return -1;
}
#endif
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
@@ -476,7 +478,7 @@ int event_queue_add_file_monitor(int eq, char *filename, int *id) {
fo.fo_ctime = st.st_ctim;
fmon_id++;
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *) fmon_id)) {
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *) (long) fmon_id)) {
uwsgi_error("port_associate()");
return -1;
}
@@ -506,7 +508,7 @@ struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
fo.fo_atime = st.st_atim;
fo.fo_mtime = st.st_mtim;
fo.fo_ctime = st.st_ctim;
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *)id)) {
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) &fo, FILE_MODIFIED|FILE_ATTRIB, (void *)(long)id)) {
uwsgi_error("port_associate()");
return NULL;
}
@@ -687,13 +689,21 @@ enum
static int timerfd_create (clockid_t __clock_id, int __flags) {
#ifdef __amd64__
return syscall(283, __clock_id, __flags);
#elif defined(__i386__)
return syscall(322, __clock_id, __flags);
#endif
}
static int timerfd_settime (int __ufd, int __flags,
__const struct itimerspec *__utmr,
struct itimerspec *__otmr) {
#ifdef __amd64__
return syscall(286, __ufd, __flags, __utmr, __otmr);
#elif defined(__i386__)
return syscall(325, __ufd, __flags, __utmr, __otmr);
#endif
}
#endif
@@ -765,7 +775,7 @@ int event_queue_add_timer(int eq, int *id, int sec) {
timer_id++;
pnotif.portnfy_port = eq;
pnotif.portnfy_user = (void *) timer_id;
pnotif.portnfy_user = (void *) (long) timer_id;
sigev.sigev_notify = SIGEV_PORT;
sigev.sigev_value.sival_ptr = &pnotif;
+7
View File
@@ -0,0 +1,7 @@
use POSIX;
open CONFIG,'welcome.ini';
dup2(fileno(CONFIG), 17);
exec './uwsgi','--ini','fd://17';
+5 -5
View File
@@ -47,7 +47,7 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
}
}
gw_pid = fork();
gw_pid = uwsgi_fork(name);
if (gw_pid < 0) {
uwsgi_error("fork()");
return NULL;
@@ -90,7 +90,7 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
ug->loop = loop;
ug->num = num;
uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) ug->pid);
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) ug->pid);
uwsgi.gateways_cnt++;
@@ -103,7 +103,7 @@ void gateway_respawn(int id) {
pid_t gw_pid;
struct uwsgi_gateway *ug = &uwsgi.gateways[id];
gw_pid = fork();
gw_pid = uwsgi_fork(ug->name);
if (gw_pid < 0) {
uwsgi_error("fork()");
return;
@@ -124,10 +124,10 @@ void gateway_respawn(int id) {
ug->pid = gw_pid;
ug->respawns++;
if (ug->respawns == 1) {
uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
else {
uwsgi_log( "respawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
uwsgi_log( "respawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
}
+1 -1
View File
@@ -92,7 +92,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
char *section_asked = "uwsgi";
char *colon;
if (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) ) {
if (uwsgi_check_scheme(file)) {
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}
+1 -1
View File
@@ -30,7 +30,7 @@ void uwsgi_json_config(char *file, char *magic_table[]) {
char *colon;
int i;
if (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6)) {
if (uwsgi_check_scheme(file)) {
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}
+1 -1
View File
@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+1 -1
View File
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+1
View File
@@ -46,6 +46,7 @@ void uwsgi_lock(void *lock) {
void uwsgi_unlock(void *lock) {
pthread_mutex_unlock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
}
void uwsgi_rwlock_init(void *lock) {
+309 -37
View File
@@ -238,7 +238,7 @@ void manage_cluster_announce(char *key, uint16_t keylen, char *val, uint16_t val
}
}
void master_loop(char **argv, char **environ) {
int master_loop(char **argv, char **environ) {
uint64_t tmp_counter;
@@ -284,15 +284,28 @@ void master_loop(char **argv, char **environ) {
#ifdef UWSGI_SNMP
int snmp_fd = -1;
#endif
int i=0;
int rlen;
int check_interval = 1;
uint64_t overload_count = 0;
uint64_t idle_count = 0;
struct uwsgi_rb_timer *min_timeout;
struct rb_root *rb_timers = uwsgi_init_rb_timer();
if (uwsgi.procname_master) {
uwsgi_set_processname(uwsgi.procname_master);
}
else if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else if (uwsgi.auto_procname) {
uwsgi_set_processname("uWSGI master");
}
uwsgi.current_time = time(NULL);
uwsgi_unix_signal(SIGHUP, grace_them_all);
@@ -318,6 +331,15 @@ void master_loop(char **argv, char **environ) {
#endif
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]);
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
#ifdef UWSGI_DEBUG
uwsgi_log("adding %d to signal poll (spooler)\n", uwsgi.shared->spooler_signal_pipe[0]);
#endif
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
}
#endif
if (uwsgi.log_master) {
#ifdef UWSGI_DEBUG
uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]);
@@ -337,6 +359,23 @@ void master_loop(char **argv, char **environ) {
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.zerg_server_fd);
uwsgi_log("*** Zerg server enabled on %s ***\n", uwsgi.zerg_server);
}
if (uwsgi.stats) {
char *tcp_port = strchr(uwsgi.stats, ':');
if (tcp_port) {
// disable deferred accept for this socket
int current_defer_accept = uwsgi.no_defer_accept;
uwsgi.no_defer_accept = 1;
uwsgi.stats_fd = bind_to_tcp(uwsgi.stats, uwsgi.listen_queue, tcp_port);
uwsgi.no_defer_accept = current_defer_accept;
}
else {
uwsgi.stats_fd = bind_to_unix(uwsgi.stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.stats_fd);
uwsgi_log("*** Stats server enabled on %s fd: %d ***\n", uwsgi.stats, uwsgi.stats_fd);
}
#ifdef UWSGI_UDP
if (uwsgi.udp_socket) {
udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
@@ -351,6 +390,9 @@ void master_loop(char **argv, char **environ) {
if (uwsgi.cheap) {
uwsgi_add_sockets_to_queue(uwsgi.master_queue);
for(i=1;i<=uwsgi.numproc;i++) {
uwsgi.workers[i].cheaped = 1;
}
uwsgi_log("cheap mode enabled: waiting for socket connection...\n");
}
@@ -450,10 +492,12 @@ void master_loop(char **argv, char **environ) {
#endif
/*
*/
// spawn mules
for(i=0;i<uwsgi.mules_cnt;i++) {
size_t mule_patch_size = 0;
uwsgi.mules[i].patch = uwsgi_string_get_list(&uwsgi.mules_patches, i, &mule_patch_size);
uwsgi_mule(i+1);
}
// spawn fat gateways
for(i=0;i<uwsgi.gateways_cnt;i++) {
@@ -481,16 +525,18 @@ void master_loop(char **argv, char **environ) {
}
}
if (uwsgi.touch_reload) {
struct uwsgi_string_list *touch_reload = uwsgi.touch_reload;
while(touch_reload) {
struct stat tr_st;
if (stat(uwsgi.touch_reload, &tr_st)) {
uwsgi_error("stat()");
uwsgi_log("unable to stat() %s, touch-reload will be disabled\n", uwsgi.touch_reload);
uwsgi.touch_reload = NULL;
if (stat(touch_reload->value, &tr_st)) {
uwsgi_log("unable to stat() %s, reload will be triggered as soon as the file is created\n", touch_reload->value);
touch_reload->custom = 0;
}
else {
uwsgi.last_touch_reload_mtime = tr_st.st_mtime;
touch_reload->custom = (uint64_t) tr_st.st_mtime;
}
touch_reload = touch_reload->next;
}
for (;;) {
@@ -504,6 +550,7 @@ void master_loop(char **argv, char **environ) {
uwsgi.lazy_respawned = 0;
}
}
if (uwsgi.master_mercy) {
if (uwsgi.master_mercy < time(NULL)) {
for(i=1;i<=uwsgi.numproc;i++) {
@@ -519,7 +566,7 @@ void master_loop(char **argv, char **environ) {
else if (uwsgi.to_heaven) { ready_to_reload++;}
else if (uwsgi.to_outworld) {
uwsgi.lazy_respawned++;
if (uwsgi_respawn_worker(i)) return;
if (uwsgi_respawn_worker(i)) return 0;
}
}
else {
@@ -532,7 +579,7 @@ void master_loop(char **argv, char **environ) {
}
if (uwsgi.respawn_workers) {
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi_respawn_worker(i)) return;
if (uwsgi_respawn_worker(i)) return 0;
}
uwsgi.respawn_workers = 0;
@@ -560,9 +607,74 @@ void master_loop(char **argv, char **environ) {
uwsgi.restore_snapshot = 0;
continue;
}
// cheaper management
if (uwsgi.cheaper) {
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
if (uwsgi.workers[i].busy == 0) {
if (overload_count > 0) overload_count--;
goto healthy;
}
}
}
overload_count++;
idle_count = 0;
}
healthy:
if (uwsgi.cheaper) {
if (overload_count > 3) {
// activate the first available worker
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].cheaped == 1 && uwsgi.workers[i].pid == 0) {
if (uwsgi_respawn_worker(i)) return 0;
overload_count = 0;
break;
}
}
}
else if (overload_count == 0) {
// how many active workers ?
idle_count++;
int active_workers = 0;
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
active_workers++;
}
}
// find the oldest worker and cheap it
if (active_workers > uwsgi.cheaper_count+1 || (idle_count > 60 && active_workers > uwsgi.cheaper_count)) {
time_t oldest_worker_spawn = INT_MAX;
int oldest_worker = 0;
idle_count = 0;
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
if (uwsgi.workers[i].last_spawn < oldest_worker_spawn) {
oldest_worker_spawn = uwsgi.workers[i].last_spawn;
oldest_worker = i;
}
}
}
if (oldest_worker > 0) {
#ifdef UWSGI_DEBUG
uwsgi_log("worker %d should die...\n", oldest_worker);
#endif
uwsgi.workers[oldest_worker].cheaped = 1;
uwsgi.workers[oldest_worker].manage_next_request = 0;
// wakeup task in case of wait
(void) kill(uwsgi.workers[oldest_worker].pid, SIGWINCH);
overload_count = 0;
}
}
}
}
if ((uwsgi.cheap || ready_to_die >= uwsgi.numproc) && uwsgi.to_hell) {
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt+uwsgi.mules_cnt);i++) {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
}
@@ -570,8 +682,8 @@ void master_loop(char **argv, char **environ) {
exit(0);
}
if ( (uwsgi.cheap || ready_to_reload >= uwsgi.numproc) && uwsgi.to_heaven) {
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt+uwsgi.mules_cnt);i++) {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
}
@@ -616,6 +728,9 @@ void master_loop(char **argv, char **environ) {
}
}
#ifdef UWSGI_AS_SHARED_LIBRARY
return -1;
#else
uwsgi_log( "running %s\n", uwsgi.binary_path);
argv[0] = uwsgi.binary_path;
//strcpy (argv[0], uwsgi.binary_path);
@@ -623,6 +738,7 @@ void master_loop(char **argv, char **environ) {
uwsgi_error("execvp()");
// never here
exit(1);
#endif
}
if (!uwsgi.cheap) {
@@ -643,6 +759,16 @@ void master_loop(char **argv, char **environ) {
else {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
if (diedpid == -1) {
if (errno == ECHILD && uwsgi.cheaper) {
if (uwsgi.to_heaven) {
ready_to_reload = uwsgi.numproc;
continue;
}
else if (uwsgi.to_hell) {
ready_to_die = uwsgi.numproc;
continue;
}
}
uwsgi_error("waitpid()");
/* here is better to reload all the uWSGI stack */
uwsgi_log( "something horrible happened...\n");
@@ -760,6 +886,12 @@ void master_loop(char **argv, char **environ) {
}
}
if (uwsgi.stats && uwsgi.stats_fd > -1) {
if (interesting_fd == uwsgi.stats_fd) {
uwsgi_send_stats(uwsgi.stats_fd);
}
}
if (uwsgi.zerg_server) {
if (interesting_fd == uwsgi.zerg_server_fd) {
struct sockaddr_un zsun;
@@ -846,7 +978,7 @@ void master_loop(char **argv, char **environ) {
uwsgi.cheap = 0;
uwsgi_del_sockets_from_queue(uwsgi.master_queue);
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi_respawn_worker(i)) return;
if (uwsgi_respawn_worker(i)) return 0;
}
break;
}
@@ -1016,23 +1148,75 @@ void master_loop(char **argv, char **environ) {
//uwsgi.workers[i].pipe[0] = -1;
}
}
#ifdef UWSGI_SPOOLER
// check for spooler signal
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) {
rlen = read(interesting_fd, &uwsgi_signal, 1);
if (rlen < 0) {
uwsgi_error("read()");
}
else if (rlen > 0) {
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("received uwsgi signal %d from the spooler\n", uwsgi_signal);
#endif
uwsgi_route_signal(uwsgi_signal);
}
else {
uwsgi_log_verbose("lost connection with the spooler\n");
close(interesting_fd);
}
}
}
#endif
}
uwsgi.current_time = time(NULL);
// checking logsize
if (uwsgi.logfile) {
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
/*
if (uwsgi.shared->logsize > 8192) {
//uwsgi_log("logsize: %d\n", uwsgi.shared->logsize);
char *new_logfile = uwsgi_malloc(strlen(uwsgi.logfile) + 14 + 1);
memset(new_logfile, 0, strlen(uwsgi.logfile) + 14 + 1);
if (!rename(uwsgi.logfile, new_logfile)) {
// close 2, reopen logfile dup'it and gracefully reload workers;
if (uwsgi.log_master) {
uwsgi.shared->logsize = lseek(uwsgi.original_log_fd, 0, SEEK_CUR);
}
else {
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
}
if (uwsgi.log_maxsize > 0 && uwsgi.shared->logsize > uwsgi.log_maxsize) {
char *rot_name = uwsgi.log_backupname;
int need_free = 0;
if (rot_name == NULL) {
char *ts_str = uwsgi_num2str((int)time(NULL));
rot_name = uwsgi_concat3(uwsgi.logfile, ".", ts_str);
free(ts_str);
need_free = 1;
}
free(new_logfile);
char message[1024];
int ret = snprintf(message, 1024, "[%d] logsize: %llu, triggering rotation to %s...\n", (int) time(NULL), (unsigned long long) uwsgi.shared->logsize, rot_name);
if (ret > 0) {
rlen = write(uwsgi.original_log_fd, message, ret);
}
if (rename(uwsgi.logfile, rot_name) == 0) {
// close 2, reopen logfile dup'it and gracefully reload workers;
int fd = open(uwsgi.logfile, O_RDWR | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP);
if (fd < 0) {
uwsgi_error_open(uwsgi.logfile);
grace_them_all(0);
}
if (dup2(fd, uwsgi.original_log_fd) < 0) {
uwsgi_error("dup2()");
grace_them_all(0);
}
}
else {
uwsgi_error("unable to rotate log: rename()");
}
if (need_free)
free(rot_name);
}
*/
}
@@ -1164,10 +1348,43 @@ void master_loop(char **argv, char **environ) {
uwsgi.workers[i].harakiri = 0;
}
}
// then for evil memory checkers
if (uwsgi.evil_reload_on_as) {
if ((rlim_t) uwsgi.workers[i].vsz_size >= uwsgi.evil_reload_on_as) {
uwsgi_log("*** EVIL RELOAD ON WORKER %d ADDRESS SPACE: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].vsz_size, uwsgi.workers[i].pid );
kill(uwsgi.workers[i].pid, SIGKILL);
uwsgi.workers[i].vsz_size = 0;
}
}
if (uwsgi.evil_reload_on_rss) {
if ((rlim_t) uwsgi.workers[i].rss_size >= uwsgi.evil_reload_on_rss) {
uwsgi_log("*** EVIL RELOAD ON WORKER %d RSS: %lld (pid: %d) ***\n", i, (long long) uwsgi.workers[i].rss_size, uwsgi.workers[i].pid );
kill(uwsgi.workers[i].pid, SIGKILL);
uwsgi.workers[i].rss_size = 0;
}
}
// need to find a better way
//uwsgi.workers[i].last_running_time = uwsgi.workers[i].running_time;
}
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (uwsgi.mules[i].harakiri > 0) {
if (uwsgi.mules[i].harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON MULE %d HANDLING SIGNAL %d (pid: %d) ***\n", i+1, uwsgi.mules[i].signum, uwsgi.mules[i].pid );
kill(uwsgi.mules[i].pid, SIGKILL);
uwsgi.mules[i].harakiri = 0;
}
}
}
#ifdef UWSGI_SPOOLER
if (uwsgi.shared->spooler_pid > 0 && uwsgi.shared->spooler_harakiri > 0) {
if (uwsgi.shared->spooler_harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uwsgi.shared->spooler_pid);
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi.shared->spooler_harakiri = 0;
}
}
#endif
#ifdef UWSGI_UDP
// check for cluster nodes
@@ -1200,19 +1417,20 @@ void master_loop(char **argv, char **environ) {
}
// check touch_reload
if (uwsgi.touch_reload && !uwsgi.to_heaven && !uwsgi.to_hell) {
struct uwsgi_string_list *touch_reload = uwsgi.touch_reload;
while (touch_reload && !uwsgi.to_heaven && !uwsgi.to_hell) {
struct stat tr_st;
if (stat(uwsgi.touch_reload, &tr_st)) {
uwsgi_error("stat()");
uwsgi_log("unable to stat() %s, touch-reload will be disabled\n", uwsgi.touch_reload);
uwsgi.touch_reload = NULL;
if (stat(touch_reload->value, &tr_st)) {
touch_reload->custom = 0;
}
else {
if (tr_st.st_mtime > uwsgi.last_touch_reload_mtime) {
uwsgi_log("*** %s has been touched... grace them all !!! ***\n", uwsgi.touch_reload);
if ((uint64_t)tr_st.st_mtime > touch_reload->custom) {
uwsgi_log("*** %s has been touched... grace them all !!! ***\n", touch_reload->value);
grace_them_all(0);
break;
}
}
touch_reload = touch_reload->next;
}
@@ -1230,12 +1448,27 @@ void master_loop(char **argv, char **environ) {
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
if (diedpid == uwsgi.shared->spooler_pid) {
uwsgi_log( "OOOPS the spooler is no more...trying respawn...\n");
uwsgi.spooler_respawned++;
uwsgi.shared->spooler_pid = spooler_start();
//event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]);
continue;
}
}
#endif
pid_found = 0;
for(i=0;i<uwsgi.mules_cnt;i++) {
if (uwsgi.mules[i].pid == diedpid) {
uwsgi_log("OOOPS mule %d crippled...trying respawn...\n", i+1);
uwsgi_mule(i+1);
pid_found = 1;
break;
}
}
if (pid_found) continue;
/* reload the gateways */
// TODO reload_gateway(diedpid);
pid_found = 0;
@@ -1276,6 +1509,37 @@ void master_loop(char **argv, char **environ) {
uwsgi.mywid = find_worker_id(diedpid);
if (uwsgi.mywid <= 0) {
// check spooler, mules, gateways and daemons
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
if (diedpid == uwsgi.shared->spooler_pid) {
uwsgi_log("spooler (pid: %d) annihilated\n", (int) diedpid);
goto next;
}
}
#endif
for(i=0;i<uwsgi.mules_cnt;i++) {
if (uwsgi.mules[i].pid == diedpid) {
uwsgi_log("mule %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
for(i=0;i<uwsgi.gateways_cnt;i++) {
if (uwsgi.gateways[i].pid == diedpid) {
uwsgi_log("gateway %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
for(i=0;i<uwsgi.shared->daemons_cnt;i++) {
if (uwsgi.shared->daemons[i].pid == diedpid) {
uwsgi_log("daemon %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
if (WIFEXITED(waitpid_status)) {
uwsgi_log("subprocess %d exited with code %d\n", (int) diedpid, WEXITSTATUS(waitpid_status));
}
@@ -1285,10 +1549,12 @@ void master_loop(char **argv, char **environ) {
else if (WIFSTOPPED(waitpid_status)) {
uwsgi_log("subprocess %d stopped\n", (int) diedpid);
}
next:
continue;
}
else {
if (uwsgi.to_heaven) {
ready_to_reload++;
uwsgi.workers[uwsgi.mywid].pid = 0;
@@ -1315,6 +1581,12 @@ void master_loop(char **argv, char **environ) {
if (uwsgi.workers[uwsgi.mywid].manage_next_request) {
uwsgi_log( "DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int)diedpid);
}
if (uwsgi.workers[uwsgi.mywid].cheaped == 1) {
uwsgi.workers[uwsgi.mywid].pid = 0;
uwsgi_log("uWSGI worker %d cheaped.\n", uwsgi.mywid);
continue;
}
gettimeofday(&last_respawn, NULL);
if (last_respawn.tv_sec == uwsgi.respawn_delta) {
last_respawn_rate++;
@@ -1338,7 +1610,7 @@ void master_loop(char **argv, char **environ) {
continue;
}
*/
if (uwsgi_respawn_worker(uwsgi.mywid)) return;
if (uwsgi_respawn_worker(uwsgi.mywid)) return 0;
}
}
+175 -37
View File
@@ -2,6 +2,8 @@
extern struct uwsgi_server uwsgi;
void worker_wakeup() {}
void master_check_cluster_nodes() {
int i;
@@ -31,24 +33,58 @@ void master_check_cluster_nodes() {
}
}
void uwsgi_fixup_fds(int wid, int muleid) {
int i;
// close the cache server
if (uwsgi.cache_server_fd != -1) {
close(uwsgi.cache_server_fd);
}
if (uwsgi.master_process) {
// fix the communication pipe
close(uwsgi.shared->worker_signal_pipe[0]);
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.workers[i].signal_pipe[0] != -1) close(uwsgi.workers[i].signal_pipe[0]);
if (i != wid) {
if (uwsgi.workers[i].signal_pipe[1] != -1) close(uwsgi.workers[i].signal_pipe[1]);
}
}
#ifdef UWSGI_SPOOLER
if (uwsgi.shared->spooler_pid != getpid()) {
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
}
#endif
if (uwsgi.shared->mule_signal_pipe[0] != -1) close(uwsgi.shared->mule_signal_pipe[0]);
if (muleid == 0) {
if (uwsgi.shared->mule_signal_pipe[1] != -1) close(uwsgi.shared->mule_signal_pipe[1]);
}
for(i=0;i<uwsgi.mules_cnt;i++) {
if (uwsgi.mules[i].signal_pipe[0] != -1) close(uwsgi.mules[i].signal_pipe[0]);
if (muleid != i+1) {
if (uwsgi.mules[i].signal_pipe[1] != -1) close(uwsgi.mules[i].signal_pipe[1]);
if (uwsgi.mules[i].queue_pipe[1] != -1) close(uwsgi.mules[i].queue_pipe[1]);
}
}
}
}
int uwsgi_respawn_worker(int wid) {
int respawns = uwsgi.workers[wid].respawn_count;
int i;
if (uwsgi.master_process) {
if (uwsgi.signal_pipe[wid][0] != -1) close(uwsgi.signal_pipe[wid][0]);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.signal_pipe[wid])) {
uwsgi_error("socketpair()\n");
}
}
pid_t pid = fork();
pid_t pid = uwsgi_fork(uwsgi.workers[wid].name);
if (pid == 0) {
signal(SIGWINCH, worker_wakeup);
uwsgi.mywid = wid;
uwsgi.mypid = getpid();
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
@@ -59,43 +95,33 @@ int uwsgi_respawn_worker(int wid) {
uwsgi.workers[uwsgi.mywid].respawn_count++;
uwsgi.workers[uwsgi.mywid].last_spawn = uwsgi.current_time;
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
uwsgi.workers[uwsgi.mywid].cheaped = 0;
uwsgi.workers[uwsgi.mywid].busy = 0;
uwsgi.workers[uwsgi.mywid].sig = 0;
// close the cache server
if (uwsgi.cache_server_fd != -1) {
close(uwsgi.cache_server_fd);
}
// reset the apps count with a copy from the master
uwsgi.workers[uwsgi.mywid].apps_cnt = uwsgi.workers[0].apps_cnt;
uwsgi_fixup_fds(wid, 0);
uwsgi.my_signal_socket = uwsgi.workers[wid].signal_pipe[1];
if (uwsgi.master_process) {
// fix the communication pipe
close(uwsgi.shared->worker_signal_pipe[0]);
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.signal_pipe[i][0] != -1) {
close(uwsgi.signal_pipe[i][0]);
}
}
uwsgi.my_signal_socket = uwsgi.signal_pipe[wid][1];
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
}
#endif
if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(1);
}
}
}
if ((uwsgi.workers[uwsgi.mywid].respawn_count || uwsgi.cheap)) {
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(1);
}
}
}
}
return 1;
}
else if (pid < 1) {
uwsgi_error("fork()");
}
else {
if (uwsgi.master_process) {
close(uwsgi.signal_pipe[wid][1]);
}
if (respawns > 0) {
uwsgi_log("Respawned uWSGI worker %d (new pid: %d)\n", wid, (int) pid);
}
@@ -257,3 +283,115 @@ void uwsgi_manage_command_cron(time_t now) {
}
#define stats_send_llu(x, y) fprintf(output, x, (long long unsigned int) y)
#define stats_send(x, y) fprintf(output, x, y)
void uwsgi_send_stats(int fd) {
int i,j;
struct sockaddr_un client_src;
struct uwsgi_app *ua;
socklen_t client_src_len = 0;
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
if (client_fd < 0) {
uwsgi_error("accept()");
return;
}
FILE *output = fdopen(client_fd, "w");
if (!output) {
uwsgi_error("fdopen()");
close(client_fd);
return;
}
stats_send("{ \"version\": \"%s\",\n", UWSGI_VERSION);
#ifdef __linux__
stats_send_llu("\"listen_queue\": %llu,\n", uwsgi.shared->ti.tcpi_unacked);
#endif
fprintf(output,"\"uid\": %d,\n", (int)(getuid()));
fprintf(output,"\"gid\": %d,\n", (int)(getgid()));
char *cwd = uwsgi_get_cwd();
stats_send("\"cwd\": \"%s\",\n", cwd);
free(cwd);
fprintf(output, "\"workers\": [\n");
for (i = 0; i < uwsgi.numproc; i++) {
fprintf(output,"\t{");
fprintf(output,"\"id\": %d, ", uwsgi.workers[i+1].id);
fprintf(output,"\"pid\": %d, ", (int) uwsgi.workers[i+1].pid);
stats_send_llu("\"requests\": %llu, ", uwsgi.workers[i+1].requests);
stats_send_llu("\"exceptions\": %llu, ", uwsgi.workers[i+1].exceptions);
stats_send_llu("\"signals\": %llu, ", uwsgi.workers[i+1].signals);
if (uwsgi.workers[i + 1].cheaped) {
fprintf(output,"\"status\": \"cheap\", ");
}
else {
if (uwsgi.workers[i + 1].sig) {
fprintf(output,"\"status\": \"sig%d\", ", uwsgi.workers[i + 1].signum);
}
else if (uwsgi.workers[i + 1].busy) {
fprintf(output,"\"status\": \"busy\", ");
}
else {
fprintf(output,"\"status\": \"idle\", ");
}
}
stats_send_llu("\"rss\": %llu, ", uwsgi.workers[i+1].rss_size);
stats_send_llu("\"vsz\": %llu, ", uwsgi.workers[i+1].vsz_size);
stats_send_llu("\"running_time\": %llu, ", uwsgi.workers[i+1].running_time);
stats_send_llu("\"last_spawn\": %llu, ", uwsgi.workers[i+1].last_spawn);
stats_send_llu("\"respawn_count\": %llu, ", uwsgi.workers[i+1].respawn_count);
stats_send_llu("\"tx\": %llu, ", uwsgi.workers[i+1].tx);
stats_send_llu("\"avg_rt\": %llu, ", uwsgi.workers[i+1].avg_response_time);
fprintf(output,"\"apps\": [\n");
for(j=0;j<uwsgi.workers[i+1].apps_cnt;j++) {
ua = &uwsgi.workers[i+1].apps[j];
fprintf(output,"\t\t{ ");
fprintf(output, "\"id\": %d, ", j);
fprintf(output, "\"modifier1\": %d, ", ua->modifier1);
fprintf(output, "\"mountpoint\": \"%.*s\", ", ua->mountpoint_len, ua->mountpoint);
stats_send_llu( "\"requests\": %llu, ", ua->requests);
stats_send_llu( "\"exceptions\": %llu, ", ua->exceptions);
if (ua->chdir) {
fprintf(output, "\"chdir\": \"%s\", ", ua->chdir);
}
else {
fprintf(output, "\"chdir\": \"\" ");
}
if (j == uwsgi.workers[i+1].apps_cnt-1) {
fprintf(output,"}\n");
}
else {
fprintf(output,"},\n");
}
}
fprintf(output,"\t\t]");
if (i == uwsgi.numproc-1) {
fprintf(output,"}\n");
}
else {
fprintf(output,"},\n");
}
}
fprintf(output,"]}\n");
fclose(output);
}
+115
View File
@@ -0,0 +1,115 @@
/*
uWSGI mules are very simple workers only managing signals or running custom code in background.
By default they born in signal-only mode, but if you patch them (passing the script/code to run) they will became fully customized daemons.
*/
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
void uwsgi_mule_handler(void);
void uwsgi_mule(int id) {
int i;
pid_t pid = uwsgi_fork(uwsgi.mules[id-1].name);
if (pid == 0) {
uwsgi.muleid = id;
// avoid race conditions
uwsgi.mules[id-1].id = id;
uwsgi.mules[id-1].pid = getpid();
uwsgi_fixup_fds(0, id);
uwsgi.my_signal_socket = uwsgi.mules[id-1].signal_pipe[1];
uwsgi.signal_socket = uwsgi.shared->mule_signal_pipe[1];
uwsgi_close_all_sockets();
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->master_fixup) {
uwsgi.p[i]->master_fixup(1);
}
}
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->post_fork) {
uwsgi.p[i]->post_fork();
}
}
if (uwsgi.mules[id-1].patch) {
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->mule) {
if (uwsgi.p[i]->mule(uwsgi.mules[id-1].patch) == 1) {
uwsgi_log("loaded mule patch %s\n", uwsgi.mules[id-1].patch);
break;
}
}
}
}
uwsgi_mule_handler();
}
else if (pid > 0) {
uwsgi.mules[id-1].id = id;
uwsgi.mules[id-1].pid = pid;
uwsgi_log("spawned uWSGI mule %d (pid: %d)\n", id, (int) pid);
}
}
void uwsgi_mule_handler() {
ssize_t len;
uint8_t uwsgi_signal;
int rlen;
int interesting_fd;
// this must be configurable
char message[65536];
int mule_queue = event_queue_init();
event_queue_add_fd_read(mule_queue, uwsgi.signal_socket);
event_queue_add_fd_read(mule_queue, uwsgi.my_signal_socket);
event_queue_add_fd_read(mule_queue, uwsgi.mules[uwsgi.muleid-1].queue_pipe[1]);
for(;;) {
rlen = event_queue_wait(mule_queue, -1, &interesting_fd);
if (rlen <= 0) {
continue;
}
if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket) {
len = read(interesting_fd, &uwsgi_signal, 1);
if (len <= 0) {
uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid);
end_me(0);
}
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.mywid);
}
}
else if (interesting_fd == uwsgi.mules[uwsgi.muleid-1].queue_pipe[1]) {
len = read(uwsgi.mules[uwsgi.muleid-1].queue_pipe[1], message, 65536);
if (len < 0) {
uwsgi_error("read()");
}
else if (len == 0) {
exit(1);
}
else {
uwsgi_log("*** mule %d received a %d bytes message\n", uwsgi.muleid, len);
}
}
}
}
+1 -1
View File
@@ -422,7 +422,7 @@ int erlang_init() {
uwsgi_log("Erlang C-Node %s registered on port %d\n", ei_thisnodename(&uerl.cnode), ntohs(sin.sin_port));
if (register_fat_gateway("erlang", erlang_loop) == NULL) {
if (register_fat_gateway("uWSGI erlang c-node", erlang_loop) == NULL) {
uwsgi_log("unable to register the erlang gateway\n");
exit(1);
}
+63 -15
View File
@@ -43,6 +43,8 @@ struct uwsgi_fastrouter {
int use_cache;
int nevents;
int queue;
int subscription_slot;
char *pattern;
@@ -61,6 +63,9 @@ struct uwsgi_fastrouter {
char *code_string_function;
struct rb_root *timeouts;
int cheap;
int i_am_cheap;
} ufr;
@@ -97,6 +102,7 @@ struct option fastrouter_options[] = {
{"fastrouter-use-base", required_argument, 0, LONG_ARGS_FASTROUTER_USE_BASE},
{"fastrouter-use-code-string", required_argument, 0, LONG_ARGS_FASTROUTER_USE_CODE_STRING},
{"fastrouter-events", required_argument, 0, LONG_ARGS_FASTROUTER_EVENTS},
{"fastrouter-cheap", no_argument, &ufr.cheap, 1},
{"fastrouter-subscription-server", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SERVER},
{"fastrouter-subscription-slot", required_argument, 0, LONG_ARGS_FASTROUTER_SUBSCRIPTION_SLOT},
{"fastrouter-timeout", required_argument, 0, LONG_ARGS_FASTROUTER_TIMEOUT},
@@ -156,8 +162,22 @@ static void close_session(struct fastrouter_session **fr_table, struct fastroute
fr_table[fr_session->fd] = NULL;
if (fr_session->instance_fd != -1) {
if (ufr.subscription_server && (fr_session->instance_failed || fr_session->status == FASTROUTER_STATUS_CONNECTING)) {
uwsgi_log("marking %.*s as failed\n", (int) fr_session->instance_address_len,fr_session->instance_address);
fr_session->un->len = 0;
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
if (fr_session->un->len > 0) {
if (ufr.subscription_dict->count > 0) {
ufr.subscription_dict->count--;
}
if (ufr.subscription_dict->count == 0 && ufr.cheap && !ufr.i_am_cheap) {
uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n");
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
while(ufr_sock) {
event_queue_del_fd(ufr.queue, ufr_sock->fd, event_queue_read());
ufr_sock = ufr_sock->next;
}
ufr.i_am_cheap = 1;
}
}
}
close(fr_session->instance_fd);
fr_table[fr_session->instance_fd] = NULL;
@@ -222,7 +242,6 @@ struct fastrouter_session *alloc_fr_session() {
void fastrouter_loop() {
int fr_queue;
int nevents;
int interesting_fd;
int new_connection;
@@ -269,7 +288,7 @@ void fastrouter_loop() {
fr_table[i] = NULL;
}
fr_queue = event_queue_init();
ufr.queue = event_queue_init();
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
@@ -295,7 +314,13 @@ void fastrouter_loop() {
uwsgi_log("uwsgi fastrouter/proxy bound on %s\n", ufr_sock->name);
event_queue_add_fd_read(fr_queue, ufr_sock->fd);
if (!ufr.cheap) {
event_queue_add_fd_read(ufr.queue, ufr_sock->fd);
}
else {
uwsgi_log("[uwsgi-fastrouter] cheap mode requested. Waiting for subscriptions...\n");
ufr.i_am_cheap = 1;
}
ufr_sock = ufr_sock->next;
}
@@ -305,7 +330,7 @@ void fastrouter_loop() {
if (ufr.subscription_server) {
ufr_subserver = bind_to_udp(ufr.subscription_server, 0, 0);
event_queue_add_fd_read(fr_queue, ufr_subserver);
event_queue_add_fd_read(ufr.queue, ufr_subserver);
if (!ufr.subscription_slot) ufr.subscription_slot = 30;
ufr.subscription_dict = uwsgi_dict_create(ufr.subscription_slot, 0);
}
@@ -331,7 +356,7 @@ void fastrouter_loop() {
}
}
nevents = event_queue_wait_multi(fr_queue, delta, events, ufr.nevents);
nevents = event_queue_wait_multi(ufr.queue, delta, events, ufr.nevents);
if (nevents == 0) {
expire_timeouts(fr_table);
@@ -364,7 +389,7 @@ void fastrouter_loop() {
fr_table[new_connection]->timeout = add_timeout(fr_table[new_connection]);
event_queue_add_fd_read(fr_queue, new_connection);
event_queue_add_fd_read(ufr.queue, new_connection);
taken = 1;
break;
}
@@ -379,12 +404,21 @@ void fastrouter_loop() {
if (interesting_fd == ufr_subserver) {
len = recv(ufr_subserver, bbuf, 4096, 0);
#ifdef UWSGI_EVENT_USE_PORT
event_queue_add_fd_read(fr_queue, ufr_subserver);
event_queue_add_fd_read(ufr.queue, ufr_subserver);
#endif
if (len > 0) {
memset(&usr, 0, sizeof(struct uwsgi_subscribe_req));
uwsgi_hooked_parse(bbuf+4, len-4, fastrouter_manage_subscription, &usr);
uwsgi_add_subscriber(ufr.subscription_dict, &usr);
if (ufr.i_am_cheap) {
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
while(ufr_sock) {
event_queue_add_fd_read(ufr.queue, ufr_sock->fd);
ufr_sock = ufr_sock->next;
}
ufr.i_am_cheap = 0;
uwsgi_log("[uwsgi-fastrouter] leaving cheap mode...\n");
}
}
}
else {
@@ -498,8 +532,22 @@ void fastrouter_loop() {
if (fr_session->instance_fd < 0) {
if (ufr.subscription_server) {
uwsgi_log("marking %.*s as failed\n", (int) fr_session->instance_address_len,fr_session->instance_address);
fr_session->un->len = 0;
uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address);
if (fr_session->un->len > 0) {
fr_session->un->len = 0;
if (ufr.subscription_dict->count > 0) {
ufr.subscription_dict->count--;
}
if (ufr.subscription_dict->count == 0 && ufr.cheap && !ufr.i_am_cheap) {
uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n");
struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets;
while(ufr_sock) {
event_queue_del_fd(ufr.queue, ufr_sock->fd, event_queue_read());
ufr_sock = ufr_sock->next;
}
ufr.i_am_cheap = 1;
}
}
}
close_session(fr_table, fr_session);
break;
@@ -508,7 +556,7 @@ void fastrouter_loop() {
fr_session->status = FASTROUTER_STATUS_CONNECTING;
fr_table[fr_session->instance_fd] = fr_session;
event_queue_add_fd_write(fr_queue, fr_session->instance_fd);
event_queue_add_fd_write(ufr.queue, fr_session->instance_fd);
}
break;
@@ -574,7 +622,7 @@ void fastrouter_loop() {
break;
}
event_queue_fd_write_to_read(fr_queue, fr_session->instance_fd);
event_queue_fd_write_to_read(ufr.queue, fr_session->instance_fd);
fr_session->status = FASTROUTER_STATUS_RESPONSE;
}
@@ -653,13 +701,13 @@ int fastrouter_init() {
if (!ufr.nevents) ufr.nevents = 64;
if (ufr.code_string_code && ufr.code_string_function) {
if (register_fat_gateway("fastrouter", fastrouter_loop) == NULL) {
if (register_fat_gateway("uWSGI fastrouter", fastrouter_loop) == NULL) {
uwsgi_log("unable to register the fastrouter gateway\n");
exit(1);
}
}
else {
if (register_gateway("fastrouter", fastrouter_loop) == NULL) {
if (register_gateway("uWSGI fastrouter", fastrouter_loop) == NULL) {
uwsgi_log("unable to register the fastrouter gateway\n");
exit(1);
}
+189 -73
View File
@@ -10,34 +10,82 @@ struct option gevent_options[] = {
#define GEVENT_SWITCH PyObject *gswitch = python_call(ugevent.greenlet_switch, ugevent.greenlet_switch_args, 0, NULL); Py_DECREF(gswitch)
#define GET_CURRENT_GREENLET python_call(ugevent.get_current, ugevent.get_current_args, 0, NULL)
#define free_req_queue uwsgi.async_queue_unused_ptr++; uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req
#define stop_the_watchers ret = PyObject_CallMethod(timer, "stop", NULL);\
if (ret) Py_DECREF(ret);\
ret = PyObject_CallMethod(watcher, "stop", NULL);\
if (ret) Py_DECREF(ret);
struct uwsgi_gevent {
PyObject *greenlet_switch;
PyObject *greenlet_switch_args;
PyObject *get_current;
PyObject *get_current_args;
PyObject *hub;
PyObject *hub_loop;
PyObject *spawn;
PyObject *greenlet_args;
PyObject *signal_args;
} ugevent;
PyObject* gevent_wait_io_and_switch(int fd, PyObject *greenlet_switch) {
PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) {
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", fd, 1);
if (!watcher) {
PyErr_Print();
return NULL;
uint8_t uwsgi_signal;
int signal_socket;
if (!PyArg_ParseTuple(args, "i:uwsgi_gevent_signal_handler", &signal_socket)) {
return NULL;
}
if (read(signal_socket, &uwsgi_signal, 1) <= 0) {
if (uwsgi.no_orphans) {
uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid);
end_me(0);
}
// close the socket to end the mess...from now on the worker is alone (no master)
else close(signal_socket);
}
else {
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid);
#endif
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid);
}
}
PyObject *ret = PyObject_CallMethod(watcher, "start", "O", greenlet_switch);
Py_DECREF(ret);
return watcher;
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_gevent_callback(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_gevent_signal(PyObject * self, PyObject * args) {
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.signal_socket));
// spawn the signal_handler greenlet
PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
Py_DECREF(new_gl);
Py_INCREF(Py_None);
return Py_None;
}
// yes copy&paste no-DRY for me :P
PyObject *py_uwsgi_gevent_my_signal(PyObject * self, PyObject * args) {
PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.my_signal_socket));
// spawn the signal_handler greenlet
PyObject *new_gl = python_call(ugevent.spawn, ugevent.signal_args, 0, NULL);
Py_DECREF(new_gl);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = find_first_available_wsgi_req();
@@ -48,21 +96,30 @@ PyObject *py_uwsgi_gevent_callback(PyObject * self, PyObject * args) {
}
uwsgi.wsgi_req = wsgi_req;
// fill wsgi_request structure
wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets );
// mark core as used
uwsgi.core[wsgi_req->async_id]->in_request = 1;
gettimeofday(&wsgi_req->start_of_request, NULL);
// enter harakiri mode
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
}
// accept the connection
if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) {
uwsgi_close_request(wsgi_req);
free_req_queue;
goto clear;
}
// hack to easily pass wsgi_req pointer to the greenlet
PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req));
// spawn the request greenlet
PyObject *new_gl = python_call(ugevent.spawn, ugevent.greenlet_args, 0, NULL);
Py_DECREF(new_gl);
@@ -71,8 +128,27 @@ clear:
return Py_None;
}
PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
PyObject *uwsgi_gevent_wait(PyObject *watcher, PyObject *timer, PyObject *current) {
PyObject *ret;
// start the io watcher
ret = PyObject_CallMethod(watcher, "start", "OO", current, watcher);
if (!ret) return NULL;
Py_DECREF(ret);
// start the timeout handler
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
if (!ret) return NULL;
Py_DECREF(ret);
// pass control to the hub
return PyObject_CallMethod(ugevent.hub, "switch", NULL);
}
PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) {
PyObject *ret;
PyObject *py_wsgi_req = PyTuple_GetItem(args, 0);
struct wsgi_request *wsgi_req = (struct wsgi_request *) PyLong_AsLong(py_wsgi_req);
int status ;
@@ -80,24 +156,47 @@ PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
PyObject *current_greenlet = GET_CURRENT_GREENLET;
PyObject *greenlet_switch = PyObject_GetAttrString(current_greenlet, "switch");
uwsgi.wsgi_req = wsgi_req;
// create a watcher for request socket
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", wsgi_req->poll.fd, 1);
if (!watcher) goto clear1;
// a timer to implement timeoit (thanks Denis)
PyObject *timer = PyObject_CallMethod(ugevent.hub_loop, "timer", "i", uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (!timer) goto clear0;
for(;;) {
// wait for data in the socket
PyObject *ret = uwsgi_gevent_wait(watcher, timer, greenlet_switch);
if (!ret) goto clear_and_stop;
// do not forget to overwrite this pointer each time !!!
uwsgi.wsgi_req = wsgi_req;
PyObject *watcher = gevent_wait_io_and_switch(wsgi_req->poll.fd, greenlet_switch);
if (!watcher) {
goto clear;
}
uwsgi.wsgi_req = wsgi_req;
status = wsgi_req->socket->proto(wsgi_req);
PyObject *ret = PyObject_CallMethod(watcher, "stop", NULL);
// we can safely decref here as watcher and timer has got a +1 for start() method
Py_DECREF(ret);
Py_DECREF(watcher);
if (status < 0) {
goto clear;
if (ret == timer) {
uwsgi_log( "timeout. skip request.\n");
goto clear_and_stop;
}
else if (status == 0) {
break;
else if (ret == watcher) {
status = wsgi_req->socket->proto(wsgi_req);
if (status < 0) {
goto clear_and_stop;
}
else if (status == 0) {
stop_the_watchers;
break;
}
}
else {
uwsgi_log("unrecognized gevent event !!!\n");
goto clear_and_stop;
}
stop_the_watchers;
}
for(;;) {
@@ -106,10 +205,21 @@ PyObject *py_uwsgi_gevent_greenlet(PyObject * self, PyObject * args) {
if (wsgi_req->async_status <= UWSGI_OK) {
goto clear;
}
// switch after each yield
GEVENT_SWITCH;
}
goto clear;
clear_and_stop:
stop_the_watchers;
clear:
Py_DECREF(timer);
clear0:
Py_DECREF(watcher);
clear1:
Py_DECREF(greenlet_switch);
Py_DECREF(current_greenlet);
uwsgi_close_request(wsgi_req);
@@ -124,8 +234,11 @@ clear:
}
PyMethodDef uwsgi_gevent_callback_method[] = { {"uwsgi_gevent_callback", py_uwsgi_gevent_callback, METH_VARARGS, ""} };
PyMethodDef uwsgi_gevent_greenlet_method[] = { {"uwsgi_gevent_greenlet", py_uwsgi_gevent_greenlet, METH_VARARGS, ""} };
PyMethodDef uwsgi_gevent_main_def[] = { {"uwsgi_gevent_main", py_uwsgi_gevent_main, METH_VARARGS, ""} };
PyMethodDef uwsgi_gevent_request_def[] = { {"uwsgi_gevent_request", py_uwsgi_gevent_request, METH_VARARGS, ""} };
PyMethodDef uwsgi_gevent_signal_def[] = { {"uwsgi_gevent_signal", py_uwsgi_gevent_signal, METH_VARARGS, ""} };
PyMethodDef uwsgi_gevent_my_signal_def[] = { {"uwsgi_gevent_my_signal", py_uwsgi_gevent_my_signal, METH_VARARGS, ""} };
PyMethodDef uwsgi_gevent_signal_handler_def[] = { {"uwsgi_gevent_signal_handler", py_uwsgi_gevent_signal_handler, METH_VARARGS, ""} };
void gevent_loop() {
@@ -139,16 +252,10 @@ void gevent_loop() {
PyObject *gevent_dict = get_uwsgi_pydict("gevent");
if (!gevent_dict) {
PyErr_Print();
exit(1);
}
if (!gevent_dict) uwsgi_pyexit;
PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
if (!gevent_version) {
PyErr_Print();
exit(1);
}
if (!gevent_version) uwsgi_pyexit;
if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) {
uwsgi_log("uWSGI requires at least gevent 1.x version\n");
@@ -156,16 +263,10 @@ void gevent_loop() {
}
ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
if (!ugevent.spawn) {
PyErr_Print();
exit(1);
}
if (!ugevent.spawn) uwsgi_pyexit;
ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
if (!ugevent.greenlet_switch) {
PyErr_Print();
exit(1);
}
if (!ugevent.greenlet_switch) uwsgi_pyexit;
ugevent.greenlet_switch_args = PyTuple_New(0);
Py_INCREF(ugevent.greenlet_switch_args);
@@ -173,52 +274,67 @@ void gevent_loop() {
PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");
PyObject *gevent_hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
if (!gevent_hub) {
PyErr_Print();
exit(1);
}
ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
if (!ugevent.hub) uwsgi_pyexit;
ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent");
if (!ugevent.get_current) {
PyErr_Print();
exit(1);
}
if (!ugevent.get_current) uwsgi_pyexit;
ugevent.get_current_args = PyTuple_New(0);
Py_INCREF(ugevent.get_current_args);
ugevent.hub_loop = PyObject_GetAttrString(gevent_hub, "loop");
if (!ugevent.hub_loop) {
PyErr_Print();
exit(1);
}
ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop");
if (!ugevent.hub_loop) uwsgi_pyexit;
// this is the watcher for server socket
PyObject *watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1);
if (!watcher) {
PyErr_Print();
exit(1);
}
if (!watcher) uwsgi_pyexit;
// main greenlet waiting for connection
PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
Py_INCREF(uwsgi_gevent_main);
PyObject *uwsgi_gevent_callback = PyCFunction_New(uwsgi_gevent_callback_method, NULL);
Py_INCREF(uwsgi_gevent_callback);
PyObject *uwsgi_gevent_greenlet = PyCFunction_New(uwsgi_gevent_greenlet_method, NULL);
Py_INCREF(uwsgi_gevent_greenlet);
// greenlet to run at each request
PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL);
Py_INCREF(uwsgi_request_greenlet);
// pre-fill the greenlet args
ugevent.greenlet_args = PyTuple_New(2);
PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_gevent_greenlet);
PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet);
if (uwsgi.signal_socket > -1) {
// and these are the watcher for signal sockets
PyObject *signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1);
if (!signal_watcher) uwsgi_pyexit;
PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_callback);
PyObject *my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
if (!my_signal_watcher) uwsgi_pyexit;
if (PyObject_CallMethod(gevent_hub, "switch", NULL)) {
PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL);
Py_INCREF(uwsgi_greenlet_signal);
PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL);
Py_INCREF(uwsgi_greenlet_my_signal);
PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL);
Py_INCREF(uwsgi_greenlet_signal_handler);
ugevent.signal_args = PyTuple_New(2);
PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler);
// start the two signal watchers
if (!PyObject_CallMethod(signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit;
if (!PyObject_CallMethod(my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit;
}
// start the main greenlet
PyObject_CallMethod(watcher, "start", "O", uwsgi_gevent_main);
if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) {
PyErr_Print();
exit(1);
}
uwsgi_log("the gevent Hub is no more :(\n");
+12 -3
View File
@@ -136,6 +136,8 @@ struct http_session {
char uss[MAX_HTTP_VEC*2];
char buffer[UMAX16];
char path_info[UMAX16];
uint16_t path_info_len;
struct uwsgi_subscriber_name *un;
@@ -325,13 +327,19 @@ int http_parse(struct http_session *h_session) {
base = ptr;
while(ptr < watermark) {
if (*ptr == '?' && !query_string) {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, base, ptr-base, &c);
// PATH_INFO must be url-decoded !!!
h_session->path_info_len = ptr-base;
http_url_decode(base, &h_session->path_info_len, h_session->path_info);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, h_session->path_info, h_session->path_info_len, &c);
query_string = ptr+1;
}
else if (*ptr == ' ') {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "REQUEST_URI", 11, base, ptr-base, &c);
if (!query_string) {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, base, ptr-base, &c);
// PATH_INFO must be url-decoded !!!
h_session->path_info_len = ptr-base;
http_url_decode(base, &h_session->path_info_len, h_session->path_info);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, h_session->path_info, h_session->path_info_len, &c);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "QUERY_STRING", 12, "", 0, &c);
}
else {
@@ -647,6 +655,7 @@ void http_loop() {
}
uhttp_session->pass_fd = is_unix(uhttp_session->instance_address, uhttp_session->instance_address_len);
uhttp_session->instance_fd = uwsgi_connectn(uhttp_session->instance_address, uhttp_session->instance_address_len, 0, 1);
@@ -882,7 +891,7 @@ int http_init() {
uhttp.server = bind_to_tcp(uhttp.socket_name, uwsgi.listen_queue, strchr(uhttp.socket_name,':'));
if (register_gateway("http", http_loop) == NULL) {
if (register_gateway("uWSGI http", http_loop) == NULL) {
uwsgi_log("unable to register the http gateway\n");
exit(1);
}
+4 -1
View File
@@ -280,7 +280,7 @@ int uwsgi_perl_init(){
struct http_status_codes *http_sc;
int argc = 3;
int argc;
uperl.embedding[0] = "";
uperl.embedding[1] = "-e";
uperl.embedding[2] = "0";
@@ -298,6 +298,9 @@ int uwsgi_perl_init(){
#else
uwsgi_log("initializing Perl environment\n");
#endif
argc = 3;
PERL_SYS_INIT3(&argc, (char ***) &uperl.embedding, &environ);
uperl.main = perl_alloc();
if (!uperl.main) {
+6 -2
View File
@@ -1,7 +1,11 @@
import os,sys
NAME='psgi'
CFLAGS = [os.popen('perl -MExtUtils::Embed -e ccopts').read().rstrip()]
LDFLAGS = [os.popen('perl -MExtUtils::Embed -e ldopts').read().rstrip()]
CFLAGS = os.popen('perl -MExtUtils::Embed -e ccopts').read().rstrip().split()
LDFLAGS = os.popen('perl -MExtUtils::Embed -e ldopts').read().rstrip().split()
LIBS = []
GCC_LIST = ['uwsgi_plmodule', 'psgi_loader', 'psgi_response', 'psgi_plugin']
for item in LDFLAGS:
if item.endswith('DynaLoader.a'):
GCC_LIST.append(item)
+7
View File
@@ -3,6 +3,11 @@
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
#ifdef UWSGI_PYPY
void gil_real_get() {}
void gil_real_release() {}
#else
void gil_real_get() {
//uwsgi_log("LOCK %d\n", uwsgi.mywid);
#ifndef PYTHREE
@@ -26,5 +31,7 @@ void gil_real_release() {
#endif
}
#endif
void gil_fake_get() {}
void gil_fake_release() {}
+2
View File
@@ -15,6 +15,7 @@ int PyFrame_GetLineNumber(PyFrameObject *frame) {
int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) {
#ifndef UWSGI_PYPY
switch(what) {
case PyTrace_CALL:
uwsgi_log("[uWSGI Python profiler] CALL: %s (line %d) -> %s %d args, stacksize %d\n",
@@ -29,6 +30,7 @@ int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, Py
PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize);
break;
}
#endif
return 0;
}
+4
View File
@@ -257,7 +257,11 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {
wsgi_req->headers_size += wsize;
PyObject *hhkey, *hhvalue;
#ifdef UWSGI_PYTHON_OLD
int hhpos = 0;
#else
Py_ssize_t hhpos = 0;
#endif
while (PyDict_Next(headers, &hhpos, &hhkey, &hhvalue)) {
if (!PyString_Check(hhkey)) continue;
+77 -4
View File
@@ -22,6 +22,57 @@ PyMethodDef uwsgi_eventfd_read_method[] = { {"uwsgi_eventfd_read", py_eventfd_re
PyMethodDef uwsgi_eventfd_write_method[] = { {"uwsgi_eventfd_write", py_eventfd_write, METH_VARARGS, ""}};
#endif
#ifdef UWSGI_MINTERPRETERS
void set_dyn_pyhome(char *home, uint16_t pyhome_len) {
char venv_version[15];
PyObject *site_module;
PyObject *pysys_dict = get_uwsgi_pydict("sys");
PyObject *pypath = pypath = PyDict_GetItemString(pysys_dict, "path");
if (!pypath) {
PyErr_Print();
exit(1);
}
// simulate a pythonhome directive
if (uwsgi.wsgi_req->pyhome_len > 0) {
PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->pyhome, uwsgi.wsgi_req->pyhome_len);
#ifdef UWSGI_DEBUG
uwsgi_debug("setting dynamic virtualenv to %.*s\n", uwsgi.wsgi_req->pyhome_len, uwsgi.wsgi_req->pyhome);
#endif
PyDict_SetItemString(pysys_dict, "prefix", venv_path);
PyDict_SetItemString(pysys_dict, "exec_prefix", venv_path);
venv_version[14] = 0;
if (snprintf(venv_version, 15, "/lib/python%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION) == -1) {
return;
}
// check here
PyString_Concat(&venv_path, PyString_FromString(venv_version));
if (PyList_Insert(pypath, 0, venv_path)) {
PyErr_Print();
}
site_module = PyImport_ImportModule("site");
if (site_module) {
PyImport_ReloadModule(site_module);
}
}
}
#endif
int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThreadState *interpreter, int app_type) {
PyObject *app_list = NULL, *applications = NULL;
@@ -94,7 +145,9 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
continue;
}
#ifdef UWSGI_DEBUG
uwsgi_log("%s = %s\n", PyString_AsString(k), PyString_AsString(env_value));
#endif
if (PyObject_SetItem(py_environ, k, env_value)) {
PyErr_Print();
@@ -109,7 +162,9 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
}
}
#ifdef UWSGI_MINTERPRETERS
if (interpreter == NULL && id) {
wi->interpreter = Py_NewInterpreter();
if (!wi->interpreter) {
uwsgi_log( "unable to initialize the new python interpreter\n");
@@ -132,6 +187,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
wi->interpreter = up.main_thread;
}
if (wsgi_req->pyhome_len) {
set_dyn_pyhome(wsgi_req->pyhome, wsgi_req->pyhome_len);
}
#else
wi->interpreter = up.main_thread;
#endif
if (wsgi_req->touch_reload_len) {
struct stat trst;
char *touch_reload = uwsgi_strncopy(wsgi_req->touch_reload, wsgi_req->touch_reload_len);
@@ -144,7 +206,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
wi->callable = up.loaders[loader](arg1);
if (!wi->callable) {
uwsgi_log("unable to load app mountpoint=%s\n", mountpoint);
uwsgi_log("unable to load app %d (mountpoint='%s') (callable not found or import error)\n", id, mountpoint);
goto doh;
}
@@ -309,13 +371,13 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
}
if (app_type == PYTHON_APP_TYPE_WSGI) {
uwsgi_log( "WSGI application %d (mountpoint=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
uwsgi_log( "WSGI application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
}
else if (app_type == PYTHON_APP_TYPE_WEB3) {
uwsgi_log( "Web3 application %d (mountpoint=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
uwsgi_log( "Web3 application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
}
else if (app_type == PYTHON_APP_TYPE_PUMP) {
uwsgi_log( "Pump application %d (mountpoint=%.*s) ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
uwsgi_log( "Pump application %d (mountpoint='%.*s') ready on interpreter %p pid: %d", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter, (int) getpid());
}
if ((wsgi_req->appid_len == 0 || (wsgi_req->appid_len = 1 && wsgi_req->appid[0] == '/')) && uwsgi.default_app == -1) {
@@ -366,6 +428,7 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
doh:
free(mountpoint);
PyErr_Print();
#ifdef UWSGI_MINTERPRETERS
if (interpreter == NULL && id) {
Py_EndInterpreter(wi->interpreter);
if (uwsgi.threads > 1) {
@@ -375,6 +438,7 @@ doh:
PyThreadState_Swap(up.main_thread);
}
}
#endif
return -1;
}
@@ -419,7 +483,9 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
PyObject *tmp_callable;
PyObject *applications;
#ifndef UWSGI_PYPY
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
#endif
char *module = (char *) arg1;
@@ -442,8 +508,10 @@ PyObject *uwsgi_uwsgi_loader(void *arg1) {
return NULL;
}
#ifndef UWSGI_PYPY
applications = PyDict_GetItemString(uwsgi_dict, "applications");
if (applications && PyDict_Check(applications)) return applications;
#endif
applications = PyDict_GetItemString(wsgi_dict, "applications");
@@ -614,6 +682,8 @@ PyObject *uwsgi_paste_loader(void *arg1) {
PyObject *uwsgi_eval_loader(void *arg1) {
#ifndef UWSGI_PYPY
char *code = (char *) arg1;
PyObject *wsgi_eval_module, *wsgi_eval_callable = NULL;
@@ -669,6 +739,9 @@ PyObject *uwsgi_eval_loader(void *arg1) {
}
return wsgi_eval_callable;
#else
return NULL;
#endif
}
+109 -58
View File
@@ -16,7 +16,7 @@ struct option uwsgi_python_options[] = {
{"module", required_argument, 0, 'w'},
{"wsgi", required_argument, 0, 'w'},
{"callable", required_argument, 0, LONG_ARGS_CALLABLE},
{"test", required_argument, 0, 'j'},
{"test", required_argument, 0, 'J'},
{"home", required_argument, 0, 'H'},
{"virtualenv", required_argument, 0, 'H'},
{"venv", required_argument, 0, 'H'},
@@ -47,8 +47,12 @@ struct option uwsgi_python_options[] = {
{"ignore-script-name", no_argument, &up.ignore_script_name, 1},
{"pep3333-input", no_argument, &up.pep3333_input, 1},
{"reload-os-env", no_argument, &up.reload_os_env, 1},
#ifndef UWSGI_PYPY
{"no-site", no_argument, &Py_NoSiteFlag, 1},
#endif
{"pyshell", no_argument, 0, LONG_ARGS_PYSHELL},
{"python", required_argument, 0, LONG_ARGS_PYTHON_RUN},
{"py", required_argument, 0, LONG_ARGS_PYTHON_RUN},
{0, 0, 0, 0},
};
@@ -71,6 +75,7 @@ struct uwsgi_help_item uwsgi_python_help[] = {
{"file <file>", "use python file instead of python module for configuration"},
{"eval <code>", "evaluate code for app configuration"},
{"ini-paste <inifile>", "path of ini config file that contains paste configuration"},
{"pyshell", "run a python interactive shell in the uwsgi environment (steals a worker)"},
{ 0, 0},
@@ -99,9 +104,14 @@ PyMethodDef uwsgi_write_method[] = { {"uwsgi_write", py_uwsgi_write, METH_VARARG
int uwsgi_python_init() {
#ifndef UWSGI_PYPY
char *pyversion = strchr(Py_GetVersion(), '\n');
uwsgi_log("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1);
#else
uwsgi_log("PyPy version: %s\n", PYPY_VERSION);
#endif
#ifndef UWSGI_PYPY
if (up.home != NULL) {
#ifdef PYTHREE
wchar_t *wpyhome;
@@ -130,9 +140,12 @@ int uwsgi_python_init() {
#endif
Py_OptimizeFlag = up.optimize;
Py_Initialize();
Py_OptimizeFlag = up.optimize;
#endif
up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL);
up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL);
@@ -155,6 +168,7 @@ int uwsgi_python_init() {
void uwsgi_python_reset_random_seed() {
#ifndef UWSGI_PYPY
PyObject *random_module, *random_dict, *random_seed;
// reinitialize the random seed (thanks Jonas Borgström)
@@ -174,6 +188,7 @@ void uwsgi_python_reset_random_seed() {
}
}
}
#endif
}
void uwsgi_python_post_fork() {
@@ -188,6 +203,7 @@ void uwsgi_python_post_fork() {
uwsgi_python_reset_random_seed();
#ifndef UWSGI_PYPY
#ifdef UWSGI_EMBEDDED
// call the post_fork_hook
PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
@@ -199,6 +215,7 @@ void uwsgi_python_post_fork() {
}
PyErr_Clear();
#endif
#endif
UWSGI_RELEASE_GIL
@@ -206,6 +223,7 @@ UWSGI_RELEASE_GIL
PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
#ifndef UWSGI_PYPY
FILE *pyfile;
struct _node *py_file_node = NULL;
PyObject *py_compiled_node, *py_file_module;
@@ -214,7 +232,7 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
char *real_filename = filename;
if (strncmp(filename, "http://", 7) && strncmp(filename, "sym://", 6) && strncmp(filename, "data://", 7)) {
if (!uwsgi_check_scheme(filename)) {
pyfile = fopen(filename, "r");
if (!pyfile) {
@@ -291,10 +309,12 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
}
return py_file_module;
#else
return NULL;
#endif
}
void init_uwsgi_vars() {
int i;
@@ -303,11 +323,6 @@ void init_uwsgi_vars() {
PyObject *modules = PyImport_GetModuleDict();
PyObject *tmp_module;
#ifdef UWSGI_MINTERPRETERS
char venv_version[15];
PyObject *site_module;
#endif
/* add cwd to pythonpath */
pysys = PyImport_ImportModule("sys");
if (!pysys) {
@@ -330,39 +345,6 @@ void init_uwsgi_vars() {
exit(1);
}
#ifdef UWSGI_MINTERPRETERS
// simulate a pythonhome directive
if (uwsgi.wsgi_req->pyhome_len > 0) {
PyObject *venv_path = UWSGI_PYFROMSTRINGSIZE(uwsgi.wsgi_req->pyhome, uwsgi.wsgi_req->pyhome_len);
#ifdef UWSGI_DEBUG
uwsgi_debug("setting dynamic virtualenv to %.*s\n", uwsgi.wsgi_req->pyhome_len, uwsgi.wsgi_req->pyhome);
#endif
PyDict_SetItemString(pysys_dict, "prefix", venv_path);
PyDict_SetItemString(pysys_dict, "exec_prefix", venv_path);
venv_version[14] = 0;
if (snprintf(venv_version, 15, "/lib/python%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION) == -1) {
return;
}
// check here
PyString_Concat(&venv_path, PyString_FromString(venv_version));
if (PyList_Insert(pypath, 0, venv_path)) {
PyErr_Print();
}
site_module = PyImport_ImportModule("site");
if (site_module) {
PyImport_ReloadModule(site_module);
}
}
#endif
if (PyList_Insert(pypath, 0, UWSGI_PYFROMSTRING(".")) != 0) {
PyErr_Print();
}
@@ -548,7 +530,12 @@ void init_uwsgi_embedded_module() {
if (PyDict_Contains(py_opt_dict, PyString_FromString(uwsgi.exported_opts[i]->key))) {
PyObject *py_opt_item = PyDict_GetItemString(py_opt_dict, uwsgi.exported_opts[i]->key);
if (PyList_Check(py_opt_item)) {
PyList_Append(py_opt_item, PyString_FromString(uwsgi.exported_opts[i]->value));
if (uwsgi.exported_opts[i]->value == NULL) {
PyList_Append(py_opt_item, Py_True);
}
else {
PyList_Append(py_opt_item, PyString_FromString(uwsgi.exported_opts[i]->value));
}
}
else {
PyObject *py_opt_list = PyList_New(0);
@@ -681,9 +668,11 @@ void init_uwsgi_embedded_module() {
init_uwsgi_module_queue(new_uwsgi_module);
}
#ifdef UWSGI_SNMP
if (uwsgi.snmp) {
init_uwsgi_module_snmp(new_uwsgi_module);
}
#endif
if (up.extension) {
up.extension();
@@ -750,7 +739,6 @@ int uwsgi_python_manage_options(int i, char *optarg) {
case LONG_ARGS_PYSHELL:
uwsgi.honour_stdin = 1;
up.pyshell = 1;
uwsgi.to_hell = 1;
return 1;
case LONG_ARGS_PYIMPORT:
uwsgi_string_new_list(&up.import_list, optarg);
@@ -774,7 +762,7 @@ int uwsgi_python_manage_options(int i, char *optarg) {
case LONG_ARGS_PYARGV:
up.argv = optarg;
return 1;
case 'j':
case 'J':
up.test_module = optarg;
return 1;
case 'H':
@@ -790,12 +778,12 @@ int uwsgi_python_manage_options(int i, char *optarg) {
#ifdef UWSGI_INI
case LONG_ARGS_INI_PASTE:
uwsgi.ini = optarg;
if (uwsgi.ini[0] != '/') {
up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", uwsgi.ini);
uwsgi_string_new_list(&uwsgi.ini,optarg);
if (optarg[0] != '/') {
up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", optarg);
}
else {
up.paste = uwsgi_concat2("config:", uwsgi.ini);
up.paste = uwsgi_concat2("config:", optarg);
}
return 1;
#endif
@@ -819,14 +807,31 @@ int uwsgi_python_manage_options(int i, char *optarg) {
return 0;
}
int uwsgi_python_mount_app(char *mountpoint, char *app) {
int uwsgi_python_mount_app(char *mountpoint, char *app, int regexp) {
int id;
uwsgi.wsgi_req->appid = mountpoint;
uwsgi.wsgi_req->appid_len = strlen(mountpoint);
if (uwsgi.single_interpreter) {
return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
id = init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, up.main_thread, PYTHON_APP_TYPE_WSGI);
}
return init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI);
id = init_uwsgi_app(LOADER_MOUNT, app, uwsgi.wsgi_req, NULL, PYTHON_APP_TYPE_WSGI);
#ifdef UWSGI_PCRE
int i;
if (regexp && id != -1) {
struct uwsgi_app *ua = &uwsgi_apps[id];
uwsgi_regexp_build(mountpoint, &ua->pattern, &ua->pattern_extra);
if (uwsgi.mywid == 0) {
for(i=1;i<=uwsgi.numproc;i++) {
uwsgi.workers[i].apps[id].pattern = ua->pattern;
uwsgi.workers[i].apps[id].pattern_extra = ua->pattern_extra;
}
}
}
#endif
return id;
}
@@ -852,7 +857,7 @@ char *uwsgi_pythonize(char *orig) {
name[i] = '_';
}
else if (name[i] == '/') {
name[i] = '.';
name[i] = '_';
}
}
@@ -869,7 +874,6 @@ void uwsgi_python_spooler_init(void) {
struct uwsgi_string_list *upli = up.spooler_import_list;
UWSGI_GET_GIL
while(upli) {
@@ -896,17 +900,22 @@ void uwsgi_python_init_apps() {
if (uwsgi.async > 1) {
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
#ifndef UWSGI_PYPY
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
#endif
}
init_pyargv();
#ifdef UWSGI_MINTERPRETERS
#ifndef UWSGI_PYPY
#ifdef UWSGI_EMBEDDED
init_uwsgi_embedded_module();
#endif
#endif
#ifdef __linux__
#ifndef PYTHREE
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
uwsgi_init_symbol_import();
#endif
#endif
@@ -1011,9 +1020,11 @@ void uwsgi_python_init_apps() {
}
if (uwsgi.profiler) {
#ifndef UWSGI_PYPY
if (!strcmp(uwsgi.profiler, "pycall")) {
PyEval_SetProfile(uwsgi_python_profiler_call, NULL);
}
#endif
}
}
@@ -1064,7 +1075,9 @@ void uwsgi_python_enable_threads() {
up.swap_ts = threaded_swap_ts;
up.reset_ts = threaded_reset_ts;
}
uwsgi_log("threads support enabled\n");
}
@@ -1075,6 +1088,9 @@ void uwsgi_python_init_thread(int core_id) {
pts = PyThreadState_New(up.main_thread->interp);
pthread_setspecific(up.upt_save_key, (void *) pts);
pthread_setspecific(up.upt_gil_key, (void *) pts);
#ifdef UWSGI_DEBUG
uwsgi_log("pts %d = %p\n", core_id, pts);
#endif
}
@@ -1128,6 +1144,7 @@ int uwsgi_python_xml(char *node, char *content) {
return 0;
}
#ifndef UWSGI_PYPY
void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
PyThreadState *tstate = PyThreadState_GET();
@@ -1142,6 +1159,7 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
}
}
#endif
char *uwsgi_python_code_string(char *id, char *code, char *function, char *key, uint16_t keylen) {
@@ -1211,6 +1229,7 @@ int uwsgi_python_signal_handler(uint8_t sig, void *handler) {
ret = python_call(handler, args, 0, NULL);
Py_DECREF(args);
if (ret) {
Py_DECREF(ret);
UWSGI_RELEASE_GIL;
return 0;
}
@@ -1329,6 +1348,7 @@ int uwsgi_python_spooler(char *filename, char *buf, uint16_t len, char *body, si
return -1;
}
#ifndef UWSGI_PYPY
void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
PyThreadState *tstate = PyThreadState_GET();
@@ -1343,21 +1363,48 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
}
}
#endif
void uwsgi_python_fixup() {
// set hacky modifier 30
uwsgi.p[30] = uwsgi.p[0];
uwsgi.p[30] = uwsgi_malloc( sizeof(struct uwsgi_plugin) );
memcpy(uwsgi.p[30], uwsgi.p[0], sizeof(struct uwsgi_plugin) );
uwsgi.p[30]->init_thread = NULL;
}
void uwsgi_python_hijack(void) {
// the pyshell will be execute only in the first worker
#ifndef UWSGI_PYPY
if (up.pyshell && uwsgi.mywid == 1) {
// re-map stdin to stdout and stderr if we are logging to a file
if (uwsgi.logfile) {
if (dup2(0, 1) < 0) {
uwsgi_error("dup2()");
}
if (dup2(0, 2) < 0) {
uwsgi_error("dup2()");
}
}
UWSGI_GET_GIL;
PyImport_ImportModule("readline");
PyRun_InteractiveLoop(stdin, "uwsgi");
exit(0);
}
#endif
}
int uwsgi_python_mule(char *opt) {
if (uwsgi_endswith(opt, ".py")) {
UWSGI_GET_GIL;
uwsgi_pyimport_by_filename("__main__", opt);
UWSGI_RELEASE_GIL;
return 1;
}
return 0;
}
struct uwsgi_plugin python_plugin = {
@@ -1369,7 +1416,7 @@ struct uwsgi_plugin python_plugin = {
.post_fork = uwsgi_python_post_fork,
.options = uwsgi_python_options,
.manage_opt = uwsgi_python_manage_options,
.short_options = "w:O:H:j:",
.short_options = "w:O:H:J:",
.request = uwsgi_request_wsgi,
.after_request = uwsgi_after_request_wsgi,
.init_apps = uwsgi_python_init_apps,
@@ -1385,8 +1432,10 @@ struct uwsgi_plugin python_plugin = {
.magic = uwsgi_python_magic,
#ifndef UWSGI_PYPY
.suspend = uwsgi_python_suspend,
.resume = uwsgi_python_resume,
#endif
.hijack_worker = uwsgi_python_hijack,
.spooler_init = uwsgi_python_spooler_init,
@@ -1394,6 +1443,8 @@ struct uwsgi_plugin python_plugin = {
.signal_handler = uwsgi_python_signal_handler,
.rpc = uwsgi_python_rpc,
.mule = uwsgi_python_mule,
.spooler = uwsgi_python_spooler,
.code_string = uwsgi_python_code_string,
+16 -2
View File
@@ -72,8 +72,9 @@ void init_pyargv() {
up.py_argv[0] = "uwsgi";
#endif
if (up.argv != NULL && !up.argc) {
up.argc++;
up.argc = 1;
if (up.argv != NULL) {
#ifdef PYTHREE
wchar_t *wcargv = malloc( sizeof( wchar_t ) * (strlen(up.argv)+1));
if (!wcargv) {
@@ -104,7 +105,20 @@ void init_pyargv() {
}
}
#ifndef UWSGI_PYPY
PySys_SetArgv(up.argc, up.py_argv);
#endif
PyObject *sys_dict = get_uwsgi_pydict("sys");
if (!sys_dict) {
uwsgi_log("unable to load python sys module !!!\n");
exit(1);
}
#ifdef PYTHREE
PyDict_SetItemString(sys_dict, "executable", PyUnicode_FromString(uwsgi.binary_path));
#else
PyDict_SetItemString(sys_dict, "executable", PyString_FromString(uwsgi.binary_path));
#endif
}
+17 -6
View File
@@ -1,6 +1,6 @@
#include "uwsgi_python.h"
#ifndef PYTHREE
#if !defined(PYTHREE) && !defined(UWSGI_PYPY)
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
@@ -363,7 +363,7 @@ static PyMethodDef symzipimporter_methods[] = {
};
static void uwsgi_symimporter_free(struct _symimporter *self) {
PyObject_Del(self);
PyObject_Del(self);
}
@@ -406,7 +406,7 @@ static PyTypeObject SymImporter_Type = {
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
0, /* tp_free */
};
static int
@@ -424,7 +424,7 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
// avoid GC !!!
name = uwsgi_concat2(name, "");
if (!uwsgi_startswith(name, "http://", 7) || !uwsgi_startswith(name, "data://", 7) || !uwsgi_startswith(name, "sym://", 6) ) {
if (uwsgi_check_scheme(name)) {
prefix = uwsgi_get_last_char(name, '/');
prefix = uwsgi_get_last_char(prefix, ':');
}
@@ -442,34 +442,44 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
return -1;
}
PyObject *stringio = PyImport_ImportModule("StringIO");
if (!stringio) {
return -1;
}
PyObject *stringio_dict = PyModule_GetDict(stringio);
if (!stringio_dict) {
return -1;
}
PyObject *stringio_stringio = PyDict_GetItemString(stringio_dict, "StringIO");
if (!stringio_stringio) {
return -1;
}
PyObject *stringio_args = PyTuple_New(1);
PyTuple_SetItem(stringio_args, 0, PyString_FromStringAndSize(body, len));
PyObject *source_code = PyInstance_New(stringio_stringio, stringio_args, NULL);
if (!source_code) {
return -1;
}
PyObject *zipfile = PyImport_ImportModule("zipfile");
if (!zipfile) {
PyErr_Print();
return -1;
}
PyObject *zipfile_dict = PyModule_GetDict(zipfile);
if (!zipfile_dict) {
return -1;
@@ -480,6 +490,7 @@ zipimporter_init(struct _symzipimporter *self, PyObject *args, PyObject *kwds)
return -1;
}
PyObject *zipfile_args = PyTuple_New(1);
PyTuple_SetItem(zipfile_args, 0, source_code);
@@ -644,7 +655,7 @@ static PyTypeObject SymZipImporter_Type = {
(initproc) symzipimporter_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
0, /* tp_free */
};
static PyTypeObject ZipImporter_Type = {
@@ -686,7 +697,7 @@ static PyTypeObject ZipImporter_Type = {
(initproc) zipimporter_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_GC_Del, /* tp_free */
0, /* tp_free */
};
+255 -35
View File
@@ -29,6 +29,9 @@ PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) {
}
else {
#endif
UWSGI_RELEASE_GIL;
pfd[0].fd = uwsgi.signal_socket;
pfd[0].events = POLLIN;
pfd[1].fd = uwsgi.my_signal_socket;
@@ -55,6 +58,7 @@ cycle:
uwsgi_error("read()");
}
else {
if (uwsgi_signal_handler(received_signal)) {
uwsgi_log_verbose("error managing signal %d on worker %d\n", received_signal, uwsgi.mywid);
}
@@ -64,8 +68,11 @@ cycle:
}
}
}
}
UWSGI_GET_GIL;
#ifdef UWSGI_ASYNC
}
#endif
@@ -827,7 +834,7 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
PyObject *what;
char *filename;
size_t chunk;
size_t chunk = 0;
off_t pos = 0;
size_t filesize = 0;
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -883,7 +890,20 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
wsgi_req->sendfile_fd_pos = pos;
// do sendfile
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
if (uwsgi.async > 1) {
ssize_t sf_len = uwsgi_sendfile(wsgi_req);
if (sf_len > 0) {
wsgi_req->response_size += sf_len;
while((size_t)wsgi_req->sendfile_fd_pos < wsgi_req->sendfile_fd_size) {
sf_len = uwsgi_sendfile(wsgi_req);
if (sf_len <= 0) break;
wsgi_req->response_size += sf_len;
}
}
}
else {
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
}
// revert to old values
wsgi_req->sendfile_fd = tmp_fd;
@@ -961,15 +981,38 @@ PyObject *py_uwsgi_log(PyObject * self, PyObject * args) {
return Py_True;
}
PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) {
#ifdef UWSGI_SPOOLER
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
Py_INCREF(Py_True);
return Py_True;
}
#endif
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
int lock_num = 0;
// the spooler cannot lock resources
#ifdef UWSGI_SPOOLER
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
}
#endif
uwsgi_lock(uwsgi.user_lock);
if (!PyArg_ParseTuple(args, "|i:lock", &lock_num)) {
return NULL;
}
if (lock_num < 0 || lock_num > uwsgi.locks) {
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
}
uwsgi_lock(uwsgi.user_lock[lock_num]);
Py_INCREF(Py_None);
return Py_None;
@@ -977,12 +1020,23 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
int lock_num = 0;
#ifdef UWSGI_SPOOLER
if (uwsgi.mypid == uwsgi.shared->spooler_pid) {
return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources");
}
#endif
if (!PyArg_ParseTuple(args, "|i:unlock", &lock_num)) {
return NULL;
}
if (lock_num < 0 || lock_num > uwsgi.locks) {
return PyErr_Format(PyExc_ValueError, "Invalid lock number");
}
uwsgi_unlock(uwsgi.user_lock);
Py_INCREF(Py_None);
@@ -1018,6 +1072,85 @@ PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_setprocname(PyObject * self, PyObject * args) {
char *name = NULL;
if (!PyArg_ParseTuple(args, "s:setprocname", &name)) {
return NULL;
}
uwsgi_set_processname(name);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_mule_msg(PyObject * self, PyObject * args) {
char *message = NULL;
Py_ssize_t message_len = 0;
int mule_id = 0;
ssize_t len;
if (!PyArg_ParseTuple(args, "s#|i:mule_msg", &message, &message_len, &mule_id)) {
return NULL;
}
if (mule_id == 0) {
}
else if (mule_id > 0 && mule_id <= uwsgi.mules_cnt) {
len = write(uwsgi.mules[mule_id-1].queue_pipe[0], message, message_len);
if (len <= 0) {
uwsgi_error("write()");
}
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_mule_get_msg(PyObject * self, PyObject * args) {
ssize_t len;
// this buffer will be configurable
char message[65536];
if (uwsgi.muleid == 0) {
return PyErr_Format(PyExc_ValueError, "you can receive mule messages only in a mule !!!");
}
UWSGI_RELEASE_GIL;
len = read(uwsgi.mules[uwsgi.muleid-1].queue_pipe[1], message, 65536);
UWSGI_GET_GIL;
if (len <= 0) {
uwsgi_error("read()");
Py_INCREF(Py_None);
return Py_None;
}
return PyString_FromStringAndSize(message, len);
}
PyObject *py_uwsgi_extract(PyObject * self, PyObject * args) {
char *name;
int len;
char *buf;
if (!PyArg_ParseTuple(args, "s:extract", &name)) {
return NULL;
}
buf = uwsgi_open_and_read(name, &len, 0, NULL);
if (buf && len > 0) {
return PyString_FromStringAndSize(buf, len);
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_sharedarea_inclong(PyObject * self, PyObject * args) {
uint64_t pos = 0;
uint64_t value = 1;
@@ -1480,7 +1613,6 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
PyObject *arg_modifier1, *arg_modifier2, *arg_timeout;
PyObject *marshalled;
PyObject *retobject;
@@ -1549,6 +1681,8 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
}
#ifndef UWSGI_PYPY
PyObject *marshalled;
switch (PyInt_AsLong(arg_modifier1)) {
case UWSGI_MODIFIER_MESSAGE_MARSHAL:
marshalled = PyMarshal_WriteObjectToString(arg_message, 1);
@@ -1563,6 +1697,7 @@ PyObject *py_uwsgi_send_multi_message(PyObject * self, PyObject * args) {
}
break;
}
#endif
}
@@ -1890,7 +2025,7 @@ PyObject *py_uwsgi_async_connect(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
PyObject *pyobj = NULL, *marshalled = NULL;
PyObject *pyobj = NULL;
int uwsgi_fd;
int modifier1 = 0;
@@ -1919,8 +2054,9 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
esize = PyString_Size(pyobj);
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
}
#ifndef UWSGI_PYPY
else {
marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
if (!marshalled) {
PyErr_Print();
goto clear;
@@ -1930,6 +2066,7 @@ PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) {
esize = PyString_Size(marshalled);
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0);
}
#endif
UWSGI_GET_GIL clear:
@@ -2030,7 +2167,7 @@ PyObject *py_uwsgi_fcgi(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) {
PyObject *destination = NULL, *pyobj = NULL, *marshalled = NULL;
PyObject *destination = NULL, *pyobj = NULL;
int modifier1 = 0;
int modifier2 = 0;
@@ -2075,8 +2212,9 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) {
esize = PyString_Size(pyobj);
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout);
}
#ifndef UWSGI_PYPY
else {
marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1);
if (!marshalled) {
PyErr_Print();
goto clear;
@@ -2086,6 +2224,7 @@ PyObject *py_uwsgi_send_message(PyObject * self, PyObject * args) {
esize = PyString_Size(marshalled);
UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, fd, cl, timeout);
}
#endif
UWSGI_GET_GIL
@@ -2132,7 +2271,7 @@ PyObject *py_uwsgi_masterpid(PyObject * self, PyObject * args) {
/* uWSGI total_requests */
PyObject *py_uwsgi_total_requests(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.workers[0].requests);
return PyLong_FromUnsignedLongLong(uwsgi.workers[0].requests);
}
/* uWSGI workers */
@@ -2162,31 +2301,57 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
}
Py_DECREF(zero);
zero = PyInt_FromLong(uwsgi.workers[i + 1].requests);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].requests);
if (PyDict_SetItemString(worker_dict, "requests", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyInt_FromLong(uwsgi.workers[i + 1].exceptions);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].signals);
if (PyDict_SetItemString(worker_dict, "signals", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].exceptions);
if (PyDict_SetItemString(worker_dict, "exceptions", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyInt_FromLong(uwsgi.workers[i + 1].rss_size);
if (uwsgi.workers[i + 1].cheaped) {
zero = PyString_FromString("cheap");
}
else {
if (uwsgi.workers[i + 1].sig) {
zero = PyString_FromFormat("sig%d",uwsgi.workers[i + 1].signum);
}
else if (uwsgi.workers[i + 1].busy) {
zero = PyString_FromString("busy");
}
else {
zero = PyString_FromString("idle");
}
}
if (PyDict_SetItemString(worker_dict, "status", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].rss_size);
if (PyDict_SetItemString(worker_dict, "rss", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyInt_FromLong(uwsgi.workers[i + 1].vsz_size);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].vsz_size);
if (PyDict_SetItemString(worker_dict, "vsz", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyFloat_FromDouble(uwsgi.workers[i + 1].running_time);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].running_time);
if (PyDict_SetItemString(worker_dict, "running_time", zero)) {
goto clear;
}
@@ -2198,20 +2363,23 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
}
Py_DECREF(zero);
zero = PyLong_FromLong(uwsgi.workers[i + 1].respawn_count);
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].respawn_count-1);
if (PyDict_SetItemString(worker_dict, "respawn_count", zero)) {
goto clear;
}
Py_DECREF(zero);
/* return a tuple of current status ! (in_request, blocking, locking, )
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].tx);
if (PyDict_SetItemString(worker_dict, "tx", zero)) {
goto clear;
}
Py_DECREF(zero);
zero = PyLong_FromLong(uwsgi.workers[i+1].in_request);
if (PyDict_SetItemString(worker_dict, "in_request", zero)) {
goto clear;
}
Py_DECREF(zero);
*/
zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].avg_response_time);
if (PyDict_SetItemString(worker_dict, "avg_rt", zero)) {
goto clear;
}
Py_DECREF(zero);
apps_tuple = PyTuple_New(uwsgi.workers[i+1].apps_cnt);
@@ -2230,8 +2398,8 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) {
PyDict_SetItemString(apps_dict, "interpreter", PyInt_FromLong((long)ua->interpreter));
PyDict_SetItemString(apps_dict, "callable", PyInt_FromLong((long)ua->interpreter));
PyDict_SetItemString(apps_dict, "requests", PyInt_FromLong(ua->requests));
PyDict_SetItemString(apps_dict, "exceptions", PyInt_FromLong(ua->exceptions));
PyDict_SetItemString(apps_dict, "requests", PyLong_FromUnsignedLongLong(ua->requests));
PyDict_SetItemString(apps_dict, "exceptions", PyLong_FromUnsignedLongLong(ua->exceptions));
if (ua->chdir) {
zero = PyString_FromString(ua->chdir);
@@ -2278,6 +2446,20 @@ PyObject *py_uwsgi_reload(PyObject * self, PyObject * args) {
return Py_True;
}
/* uWSGI stop */
PyObject *py_uwsgi_stop(PyObject * self, PyObject * args) {
if (kill(uwsgi.workers[0].pid, SIGQUIT)) {
uwsgi_error("kill()");
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(Py_True);
return Py_True;
}
/* blocking hint */
PyObject *py_uwsgi_set_blocking(PyObject * self, PyObject * args) {
@@ -2293,15 +2475,19 @@ PyObject *py_uwsgi_set_blocking(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_request_id(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.workers[uwsgi.mywid].requests);
return PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].requests);
}
PyObject *py_uwsgi_worker_id(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.mywid);
}
PyObject *py_uwsgi_mule_id(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.muleid);
}
PyObject *py_uwsgi_logsize(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.shared->logsize);
return PyLong_FromUnsignedLongLong(uwsgi.shared->logsize);
}
PyObject *py_uwsgi_mem(PyObject * self, PyObject * args) {
@@ -2310,8 +2496,8 @@ PyObject *py_uwsgi_mem(PyObject * self, PyObject * args) {
get_memusage();
PyTuple_SetItem(ml, 0, PyLong_FromLong(uwsgi.workers[uwsgi.mywid].rss_size));
PyTuple_SetItem(ml, 1, PyLong_FromLong(uwsgi.workers[uwsgi.mywid].vsz_size));
PyTuple_SetItem(ml, 0, PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].rss_size));
PyTuple_SetItem(ml, 1, PyLong_FromUnsignedLongLong(uwsgi.workers[uwsgi.mywid].vsz_size));
return ml;
@@ -2321,7 +2507,7 @@ PyObject *py_uwsgi_cl(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = current_wsgi_req();
return PyLong_FromLong(wsgi_req->post_cl);
return PyLong_FromUnsignedLongLong(wsgi_req->post_cl);
}
@@ -2463,6 +2649,7 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
goto clear;
}
// use a normal fork here
grunt_pid = fork();
if (grunt_pid < 0) {
uwsgi_error("fork()");
@@ -2615,6 +2802,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"send_message", py_uwsgi_send_message, METH_VARARGS, ""},
{"send_multi_message", py_uwsgi_send_multi_message, METH_VARARGS, ""},
{"reload", py_uwsgi_reload, METH_VARARGS, ""},
{"stop", py_uwsgi_stop, METH_VARARGS, ""},
{"workers", py_uwsgi_workers, METH_VARARGS, ""},
{"masterpid", py_uwsgi_masterpid, METH_VARARGS, ""},
{"total_requests", py_uwsgi_total_requests, METH_VARARGS, ""},
@@ -2625,6 +2813,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"sorry_i_need_to_block", py_uwsgi_set_blocking, METH_VARARGS, ""},
{"request_id", py_uwsgi_request_id, METH_VARARGS, ""},
{"worker_id", py_uwsgi_worker_id, METH_VARARGS, ""},
{"mule_id", py_uwsgi_mule_id, METH_VARARGS, ""},
{"log", py_uwsgi_log, METH_VARARGS, ""},
{"log_this_request", py_uwsgi_log_this, METH_VARARGS, ""},
{"disconnect", py_uwsgi_disconnect, METH_VARARGS, ""},
@@ -2634,6 +2823,8 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
{"cl", py_uwsgi_cl, METH_VARARGS, ""},
{"setprocname", py_uwsgi_setprocname, METH_VARARGS, ""},
{"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""},
{"attach_daemon", py_uwsgi_attach_daemon, METH_VARARGS, ""},
@@ -2684,11 +2875,16 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""},
{"recv_frame", py_uwsgi_recv_frame, METH_VARARGS, ""},
{"close", py_uwsgi_close, METH_VARARGS, ""},
{"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""},
{"fcgi", py_uwsgi_fcgi, METH_VARARGS, ""},
{"parsefile", py_uwsgi_parse_file, METH_VARARGS, ""},
{"embedded_data", py_uwsgi_embedded_data, METH_VARARGS, ""},
{"extract", py_uwsgi_extract, METH_VARARGS, ""},
{"mule_msg", py_uwsgi_mule_msg, METH_VARARGS, ""},
{"mule_get_msg", py_uwsgi_mule_get_msg, METH_VARARGS, ""},
//{"call_hook", py_uwsgi_call_hook, METH_VARARGS, ""},
{NULL, NULL},
@@ -2902,12 +3098,12 @@ PyObject *py_uwsgi_queue_set(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_queue_slot(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.queue_header->pos);
return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pos);
}
PyObject *py_uwsgi_queue_pull_slot(PyObject * self, PyObject * args) {
return PyInt_FromLong(uwsgi.queue_header->pull_pos);
return PyLong_FromUnsignedLongLong(uwsgi.queue_header->pull_pos);
}
@@ -2996,23 +3192,44 @@ PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
long num = 0;
uint64_t size = 0;
char *message;
PyObject *res, *zero;
PyObject *res = NULL, *zero;
uint64_t base;
if (!PyArg_ParseTuple(args, "l:queue_last", &num)) {
if (!PyArg_ParseTuple(args, "|l:queue_last", &num)) {
return NULL;
}
if (uwsgi.queue_size) {
res = PyList_New(0);
if (num > 0) {
res = PyList_New(0);
}
uwsgi_rlock(uwsgi.queue_lock);
if (uwsgi.queue_header->pos > 0) {
base = uwsgi.queue_header->pos-1;
}
else {
base = uwsgi.queue_size-1;
}
if (num == 0) {
message = uwsgi_queue_get(base, &size);
if (message && size) {
res = PyString_FromStringAndSize(message, size);
}
else {
Py_INCREF(Py_None);
res = Py_None;
}
uwsgi_rwunlock(uwsgi.queue_lock);
return res;
}
if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
while(num) {
message = uwsgi_queue_get(base, &size);
if (message && size) {
@@ -3064,6 +3281,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
uwsgi_simple_message_string(remote, 111, 0, key, keylen, buffer, &valsize16, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (valsize16 > 0) {
value = buffer;
valsize = valsize16;
}
}
else if (uwsgi.cache_max_items) {
@@ -3196,7 +3414,7 @@ void init_uwsgi_module_queue(PyObject * current_uwsgi_module) {
Py_DECREF(func);
}
PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyInt_FromLong(uwsgi.queue_size));
PyDict_SetItemString(uwsgi_module_dict, "queue_size", PyLong_FromUnsignedLongLong(uwsgi.queue_size));
}
@@ -3217,6 +3435,7 @@ void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
}
}
#ifdef UWSGI_SNMP
PyObject *py_snmp_counter32(PyObject * self, PyObject * args) {
uint8_t oid_num;
@@ -3337,6 +3556,7 @@ void init_uwsgi_module_snmp(PyObject * current_uwsgi_module) {
uwsgi_log( "SNMP python functions initialized.\n");
}
#endif
#endif
+11 -1
View File
@@ -20,6 +20,7 @@
#define LONG_ARGS_WSGI_LITE LONG_ARGS_PYTHON_BASE + 10
#define LONG_ARGS_PYSHELL LONG_ARGS_PYTHON_BASE + 11
#define LONG_ARGS_SPOOLER_PYIMPORT LONG_ARGS_PYTHON_BASE + 12
#define LONG_ARGS_PYTHON_RUN LONG_ARGS_PYTHON_BASE + 13
#define PYTHON_APP_TYPE_WSGI 0
#define PYTHON_APP_TYPE_WEB3 1
@@ -29,6 +30,7 @@
#if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2
#define Py_ssize_t ssize_t
#define UWSGI_PYTHON_OLD
#endif
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
@@ -94,9 +96,11 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
#define LOADER_MAX 8
#define UWSGI_PY_READLINE_BUFSIZE 1024
typedef struct uwsgi_Input {
PyObject_HEAD
char readline[1024];
char readline[UWSGI_PY_READLINE_BUFSIZE];
size_t readline_size;
size_t readline_max_size;
size_t readline_pos;
@@ -264,6 +268,12 @@ void uwsgi_python_reset_random_seed(void);
char *uwsgi_pythonize(char *);
#ifdef UWSGI_PYPY
#undef UWSGI_MINTERPRETERS
#endif
#define uwsgi_pyexit {PyErr_Print();exit(1);}
#ifdef __linux__
#ifndef PYTHREE
int uwsgi_init_symbol_import(void);
+24 -16
View File
@@ -4,28 +4,36 @@ from distutils import sysconfig
NAME='python'
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter']
#OBJ_LIST = ['/usr/lib/libpython2.6.a']
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ]
if 'pypy_version_info' in sys.__dict__:
CFLAGS.append('-DUWSGI_PYPY')
LDFLAGS = []
LIBS = sysconfig.get_config_var('LIBS').split() + sysconfig.get_config_var('SYSLIBS').split()
if not sysconfig.get_config_var('Py_ENABLE_SHARED'):
if not 'UWSGI_PYTHON_NOLIB' in os.environ:
LIBS = sysconfig.get_config_var('LIBS').split() + sysconfig.get_config_var('SYSLIBS').split()
if not sysconfig.get_config_var('Py_ENABLE_SHARED'):
LIBS.append('-L' + sysconfig.get_config_var('LIBPL'))
else:
try:
LDFLAGS.append("-L%s" % sysconfig.get_config_var('LIBDIR'))
os.environ['LD_RUN_PATH'] = "%s" % (sysconfig.get_config_var('LIBDIR'))
except:
LDFLAGS.append("-L%s/lib" % sysconfig.PREFIX)
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
version = sysconfig.get_config_var('VERSION')
try:
version = version + sys.abiflags
except:
pass
LIBS.append('-lpython' + version)
else:
try:
LDFLAGS.append("-L%s" % sysconfig.get_config_var('LIBDIR'))
os.environ['LD_RUN_PATH'] = "%s" % (sysconfig.get_config_var('LIBDIR'))
except:
LDFLAGS.append("-L%s/lib" % sysconfig.PREFIX)
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
version = sysconfig.get_config_var('VERSION')
try:
version = version + sys.abiflags
except:
pass
LIBS.append('-lpython' + version)
LIBS = []
#if str(PYLIB_PATH) != '':
# libs.insert(0,'-L' + PYLIB_PATH)
+2 -2
View File
@@ -46,11 +46,11 @@ PyObject *uwsgi_Input_getline(uwsgi_Input *self) {
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data");
}
if (self->readline_max_size > 0 && self->readline_max_size < 1024) {
if (self->readline_max_size > 0 && self->readline_max_size < UWSGI_PY_READLINE_BUFSIZE) {
rlen = read(wsgi_req->poll.fd, self->readline, self->readline_max_size);
}
else {
rlen = read(wsgi_req->poll.fd, self->readline, 1024);
rlen = read(wsgi_req->poll.fd, self->readline, UWSGI_PY_READLINE_BUFSIZE);
}
if (rlen <= 0) {
UWSGI_GET_GIL
-6
View File
@@ -191,9 +191,6 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
UWSGI_RELEASE_GIL
iov_ret = wsgi_req->socket->proto_writev_header(wsgi_req, iov_ptr, iov_size);
UWSGI_GET_GIL
if (iov_ret < 0) {
uwsgi_error("writev()");
}
wsgi_req->headers_size += iov_ret;
iov_ptr += iov_size;
remains -= iov_size;
@@ -202,9 +199,6 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
UWSGI_RELEASE_GIL
wsgi_req->headers_size = wsgi_req->socket->proto_writev_header(wsgi_req, wsgi_req->hvec, j + 1);
UWSGI_GET_GIL
if (wsgi_req->headers_size < 0) {
uwsgi_error("writev()");
}
#endif
//uwsgi_log("%d %p\n", wsgi_req->poll.fd, up.wsgi_writeout);
+20 -2
View File
@@ -22,12 +22,15 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
#endif
#ifdef UWSGI_DEBUG
uwsgi_log("%p %d %p %d\n", pydictkey, wsgi_req->hvec[i].iov_len, pydictvalue, wsgi_req->hvec[i + 1].iov_len);
#endif
PyDict_SetItem(wsgi_req->async_environ, pydictkey, pydictvalue);
Py_DECREF(pydictkey);
Py_DECREF(pydictvalue);
}
if (wsgi_req->uh.modifier1 == UWSGI_MODIFIER_MANAGE_PATH_INFO) {
wsgi_req->uh.modifier1 = 0;
pydictkey = PyDict_GetItemString(wsgi_req->async_environ, "SCRIPT_NAME");
@@ -44,6 +47,8 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
}
}
#ifndef UWSGI_PYPY
// if async_post is mapped as a file, directly use it as wsgi.input
if (wsgi_req->async_post) {
#ifdef PYTHREE
@@ -62,7 +67,9 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
}
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_req->async_input);
#endif
#ifdef UWSGI_SENDFILE
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.file_wrapper", wi->sendfile);
@@ -78,12 +85,16 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.version", wi->gateway_version);
zero = PyFile_FromFile(stderr, "wsgi_input", "w", NULL);
#ifndef UWSGI_PYPY
zero = PyFile_FromFile(stderr, "wsgi_errors", "w", NULL);
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.errors", zero);
Py_DECREF(zero);
#endif
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.run_once", Py_False);
if (uwsgi.threads > 1) {
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.multithread", Py_True);
}
@@ -117,10 +128,13 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
wsgi_req->async_app = wi->callable;
// export .env only in non-threaded mode
#ifndef UWSGI_PYPY
if (uwsgi.threads < 2) {
PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
}
#endif
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", wi->uwsgi_version);
@@ -180,7 +194,11 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
#ifdef UWSGI_SENDFILE
#ifdef __FreeBSD__
if ( ((wsgi_req->sendfile_obj == wsgi_req->async_result) || ( wsgi_req->sendfile_fd_size > 0 && wsgi_req->response_size < wsgi_req->sendfile_fd_size)) && wsgi_req->sendfile_fd != -1) {
#else
if (wsgi_req->sendfile_obj == wsgi_req->async_result && wsgi_req->sendfile_fd != -1) {
#endif
sf_len = uwsgi_sendfile(wsgi_req);
if (sf_len < 1) goto clear;
wsgi_req->response_size += sf_len;
+75
View File
@@ -0,0 +1,75 @@
#include "../python/uwsgi_python.h"
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
extern char **environ;
PyObject *u_run(PyObject *self, PyObject *args) {
char **argv;
size_t size = 2;
int i;
if (PyTuple_Size(args) < 1) {
return PyErr_Format(PyExc_ValueError, "you have to specify at least one uWSGI option to run() it");
}
PyObject *the_arg = PyTuple_GetItem(args, 0);
if (PyList_Check(the_arg)) {
size = PyList_Size(the_arg) + 2;
}
else if (PyTuple_Check(the_arg)) {
size = PyTuple_Size(the_arg) + 2;
}
else if (PyString_Check(the_arg)) {
size = 3;
}
argv = uwsgi_malloc(sizeof(char *) * size);
memset(argv, 0, sizeof(char *) * size);
// will be overwritten
argv[0] = "uwsgi";
if (PyList_Check(the_arg)) {
for(i=0;i<PyList_Size(the_arg);i++) {
argv[i+1] = PyString_AsString( PyList_GetItem(the_arg, i) );
}
}
else if (PyTuple_Check(the_arg)) {
for(i=0;i<PyTuple_Size(the_arg);i++) {
argv[i+1] = PyString_AsString( PyTuple_GetItem(the_arg, i) );
}
}
else if (PyString_Check(the_arg)) {
argv[1] = PyString_AsString( the_arg );
}
uwsgi_init(size-1, argv, environ);
Py_INCREF(Py_None);
return Py_None;
}
PyMethodDef methods[] = {
{"run", u_run, METH_VARARGS, "run the uWSGI server"},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
initpyuwsgi()
{
(void) Py_InitModule("pyuwsgi", methods);
}
int pyuwsgi_init() { return 0; }
struct uwsgi_plugin pyuwsgi_plugin = {
.name = "pyuwsgi",
.init = pyuwsgi_init,
};
+11
View File
@@ -0,0 +1,11 @@
from distutils import sysconfig
import os
os.environ['UWSGI_PYTHON_NOLIB'] = '1'
NAME='pyuwsgi'
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
LDFLAGS = []
LIBS = []
GCC_LIST = ['pyuwsgi']
+6
View File
@@ -9,6 +9,7 @@ struct option uwsgi_rack_options[] = {
{"rails", required_argument, 0, LONG_ARGS_RAILS},
{"rack", required_argument, 0, LONG_ARGS_RACK},
{"ruby-gc-freq", required_argument, 0, LONG_ARGS_RUBY_GC_FREQ},
{"rbshell", optional_argument, 0, LONG_ARGS_RUBY_SHELL},
{0, 0, 0, 0},
@@ -920,6 +921,9 @@ int uwsgi_rack_mount_app(char *mountpoint, char *app) {
}
*/
void uwsgi_rack_hijack(void) {
}
struct uwsgi_plugin rack_plugin = {
.name = "rack",
@@ -932,6 +936,8 @@ struct uwsgi_plugin rack_plugin = {
.signal_handler = uwsgi_rack_signal_handler,
.hijack = uwsgi_rack_hijack,
.init_apps = uwsgi_rack_init_apps,
//.mount_app = uwsgi_rack_mount_app,
.manage_xml = uwsgi_rack_xml,
+3
View File
@@ -6,6 +6,7 @@
#define LONG_ARGS_RAILS LONG_ARGS_RACK_BASE + 1
#define LONG_ARGS_RUBY_GC_FREQ LONG_ARGS_RACK_BASE + 2
#define LONG_ARGS_RACK LONG_ARGS_RACK_BASE + 3
#define LONG_ARGS_RUBY_SHELL LONG_ARGS_RACK_BASE + 4
#ifndef RUBY19
#define rb_errinfo() ruby_errinfo
@@ -59,6 +60,8 @@ struct uwsgi_rack {
pthread_mutex_t gvl;
int rb_shell;
};
void uwsgi_ruby_exception(void);
+43 -8
View File
@@ -46,6 +46,12 @@ static uint16_t http_add_uwsgi_header(struct wsgi_request *wsgi_req, char *hh, i
wsgi_req->if_modified_since = val;
wsgi_req->if_modified_since_len = vallen;
}
else if (!uwsgi_strncmp("X_FORWARDED_SSL", 15, hh, keylen)) {
if (vallen == 2 && val[0] == 'o' && val[1] == 'n') {
wsgi_req->scheme = "https";
wsgi_req->scheme_len = 5;
}
}
else if (uwsgi.vhost_host && !uwsgi_strncmp("HOST", 4, hh, keylen)) {
wsgi_req->host = val;
wsgi_req->host_len = vallen;
@@ -100,6 +106,8 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
char ip[INET_ADDRSTRLEN+1];
struct sockaddr_in *http_sin = (struct sockaddr_in *) &wsgi_req->c_addr;
wsgi_req->path_info_pos = -1;
// REQUEST_METHOD
while (ptr < watermark) {
if (*ptr == ' ') {
@@ -116,9 +124,19 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
base = ptr;
while (ptr < watermark) {
if (*ptr == '?' && !query_string) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) {
wsgi_req->path_info = watermark;
wsgi_req->path_info_len = ptr - base;
http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info);
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len);
}
else {
uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n");
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
}
wsgi_req->path_info_pos = 3;
query_string = ptr + 1;
}
else if (*ptr == ' ') {
@@ -127,9 +145,19 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
wsgi_req->uri_len = ptr - base;
if (!query_string) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) {
wsgi_req->path_info = watermark;
wsgi_req->path_info_len = ptr - base;
http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info);
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len);
}
else {
uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n");
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
}
wsgi_req->path_info_pos = 5;
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0);
}
else {
@@ -161,7 +189,10 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
}
// SCRIPT_NAME
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SCRIPT_NAME", 11, "", 0);
if (!uwsgi.manage_script_name) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SCRIPT_NAME", 11, "", 0);
}
// SERVER_NAME
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_NAME", 11, uwsgi.hostname, uwsgi.hostname_len);
@@ -261,7 +292,11 @@ int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) {
len = read(wsgi_req->poll.fd, wsgi_req->proto_parser_buf + wsgi_req->proto_parser_pos, uwsgi.buffer_size - wsgi_req->proto_parser_pos);
if (len <= 0) {
free(wsgi_req->proto_parser_buf);
uwsgi_error("recv()");
if (len < 0) {
uwsgi_error("recv()");
}
// this is simple ping packet
else { return -2; }
return -1;
}
+24 -4
View File
@@ -115,17 +115,37 @@ int uwsgi_proto_uwsgi_parser(struct wsgi_request *wsgi_req) {
}
ssize_t uwsgi_proto_uwsgi_writev_header(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
return writev(wsgi_req->poll.fd, iovec, iov_len);
ssize_t wlen = writev(wsgi_req->poll.fd, iovec, iov_len);
if (wlen < 0) {
uwsgi_req_error("writev()");
return 0;
}
return wlen;
}
ssize_t uwsgi_proto_uwsgi_writev(struct wsgi_request * wsgi_req, struct iovec * iovec, size_t iov_len) {
return writev(wsgi_req->poll.fd, iovec, iov_len);
ssize_t wlen = writev(wsgi_req->poll.fd, iovec, iov_len);
if (wlen < 0) {
uwsgi_req_error("writev()");
return 0;
}
return wlen;
}
ssize_t uwsgi_proto_uwsgi_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
return write(wsgi_req->poll.fd, buf, len);
ssize_t wlen = write(wsgi_req->poll.fd, buf, len);
if (wlen < 0) {
uwsgi_req_error("write()");
return 0;
}
return wlen;
}
ssize_t uwsgi_proto_uwsgi_write_header(struct wsgi_request * wsgi_req, char *buf, size_t len) {
return write(wsgi_req->poll.fd, buf, len);
ssize_t wlen = write(wsgi_req->poll.fd, buf, len);
if (wlen < 0) {
uwsgi_req_error("write()");
return 0;
}
return wlen;
}
+76 -12
View File
@@ -355,7 +355,7 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
exit(1);
}
else if (rlen == 0) {
uwsgi_log( "timeout waiting for header. skip request.\n");
uwsgi_log( "timeout. skip request.\n");
//close(upoll->fd);
return 0;
}
@@ -366,7 +366,10 @@ int uwsgi_parse_packet(struct wsgi_request *wsgi_req, int timeout) {
status = uwsgi_proto_uwsgi_parser(wsgi_req);
}
if (status < 0) {
uwsgi_log("error parsing request\n");
if (status == -1)
uwsgi_log("error parsing request\n");
else if (status == -2)
uwsgi_log("open-close packet (ping/check) received\n");
//close(upoll->fd);
return 0;
}
@@ -496,7 +499,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
ptrbuf = buffer;
bufferend = ptrbuf + wsgi_req->uh.pktsize;
int i, script_name= -1, path_info= -1;
int i, script_name= -1;
/* set an HTTP 500 status as default */
wsgi_req->status = 500;
@@ -508,6 +511,8 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
return i;
}
wsgi_req->path_info_pos = -1;
while (ptrbuf < bufferend) {
if (ptrbuf + 2 < bufferend) {
memcpy(&strsize, ptrbuf, 2);
@@ -546,7 +551,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
else if (!uwsgi_strncmp("PATH_INFO", 9, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
wsgi_req->path_info = ptrbuf;
wsgi_req->path_info_len = strsize;
path_info = wsgi_req->var_cnt + 1;
wsgi_req->path_info_pos = wsgi_req->var_cnt + 1;
#ifdef UWSGI_DEBUG
uwsgi_debug("PATH_INFO=%.*s\n", wsgi_req->path_info_len, wsgi_req->path_info);
#endif
@@ -567,7 +572,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
wsgi_req->method = ptrbuf;
wsgi_req->method_len = strsize;
}
else if (!uwsgi_strncmp("REMOTE_ADDR", 11, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
else if (!uwsgi.log_x_forwarded_for && !uwsgi_strncmp("REMOTE_ADDR", 11, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
wsgi_req->remote_addr = ptrbuf;
wsgi_req->remote_addr_len = strsize;
}
@@ -652,6 +657,10 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
wsgi_req->if_modified_since = ptrbuf;
wsgi_req->if_modified_since_len = strsize;
}
else if (uwsgi.log_x_forwarded_for && !uwsgi_strncmp("HTTP_X_FORWARDED_FOR", 20, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
wsgi_req->remote_addr = ptrbuf;
wsgi_req->remote_addr_len = strsize;
}
else if (!uwsgi_strncmp("CONTENT_TYPE", 12, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
wsgi_req->content_type = ptrbuf;
wsgi_req->content_type_len = strsize;
@@ -749,7 +758,7 @@ next:
}
if (uwsgi.manage_script_name) {
if (uwsgi_apps_cnt > 0 && wsgi_req->path_info_len > 1) {
if (uwsgi_apps_cnt > 0 && wsgi_req->path_info_len > 1 && wsgi_req->path_info_pos != -1) {
// starts with 1 as the 0 app is the default (/) one
int best_found = 0;
char *orig_path_info = wsgi_req->path_info;
@@ -760,12 +769,15 @@ next:
uwsgi_log( "max vec size reached. skip this var.\n");
return -1;
}
wsgi_req->var_cnt++;
wsgi_req->hvec[wsgi_req->var_cnt].iov_base = "SCRIPT_NAME";
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = 11;
wsgi_req->var_cnt++;
script_name = wsgi_req->var_cnt;
wsgi_req->hvec[script_name].iov_base = "";
wsgi_req->hvec[script_name].iov_len = 0;
wsgi_req->var_cnt++;
}
for(i=0;i<uwsgi_apps_cnt;i++) {
//uwsgi_log("app mountpoint = %.*s\n", uwsgi_apps[i].mountpoint_len, uwsgi_apps[i].mountpoint);
if (orig_path_info_len >= uwsgi_apps[i].mountpoint_len) {
@@ -779,8 +791,8 @@ next:
wsgi_req->hvec[script_name].iov_base = wsgi_req->script_name;
wsgi_req->hvec[script_name].iov_len = wsgi_req->script_name_len;
wsgi_req->hvec[path_info].iov_base = wsgi_req->path_info;
wsgi_req->hvec[path_info].iov_len = wsgi_req->path_info_len;
wsgi_req->hvec[wsgi_req->path_info_pos].iov_base = wsgi_req->path_info;
wsgi_req->hvec[wsgi_req->path_info_pos].iov_len = wsgi_req->path_info_len;
#ifdef UWSGI_DEBUG
uwsgi_log("managed SCRIPT_NAME = %.*s PATH_INFO = %.*s\n", wsgi_req->script_name_len, wsgi_req->script_name, wsgi_req->path_info_len, wsgi_req->path_info);
#endif
@@ -1324,6 +1336,48 @@ int uwsgi_simple_send_string(char *socket_name, uint8_t modifier1, uint8_t modif
return 0;
}
char *uwsgi_get_mime_type(char *name, int namelen, int *size) {
int i;
int count = 0;
char *ext = NULL;
for(i=namelen-1;i>=0;i--) {
if (!isalnum( (int)name[i])) {
if (name[i] == '.') {
ext = name+(namelen-count);
break;
}
}
count++;
}
if (ext) {
struct uwsgi_dyn_dict *udd = uwsgi.mimetypes;
while(udd) {
if (!uwsgi_strncmp(ext, count, udd->key, udd->keylen)) {
udd->hits++;
// auto optimization
if (udd->prev) {
if (udd->hits > udd->prev->hits) {
struct uwsgi_dyn_dict *udd_parent = udd->prev->prev, *udd_prev = udd->prev;
if (udd_parent) {
udd_parent->next = udd;
}
udd_prev->prev = udd;
udd_prev->next = udd->next;
udd->prev = udd_parent;
udd->next = udd_prev;
}
}
*size = udd->vallen;
return udd->value;
}
udd = udd->next;
}
}
return NULL;
}
int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_t document_root_len, char *path_info, uint16_t path_info_len, char *orig_document_root, uint16_t orig_document_root_len) {
@@ -1348,6 +1402,8 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
return -1;
}
if (!stat(real_filename, &st)) {
int mime_type_size = 0;
char *mime_type = uwsgi_get_mime_type(path_info, path_info_len, &mime_type_size);
if (wsgi_req->if_modified_since_len) {
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
if (st.st_mtime <= ims) {
@@ -1380,11 +1436,19 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
while(ah) {
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ah->value, ah->len);
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
wsgi_req->header_cnt++;
ah = ah->next;
}
if (mime_type_size > 0 && mime_type) {
wsgi_req->header_cnt++;
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "Content-Type: ", 14);
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, mime_type, mime_type_size);
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "\r\n", 2);
}
if (uwsgi.file_serve_mode == 1) {
wsgi_req->header_cnt = 2;
wsgi_req->header_cnt += 2;
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Accel-Redirect: ", 18);
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, orig_document_root, orig_document_root_len);
if (orig_document_root[orig_document_root_len-1] != '/') {
@@ -1396,7 +1460,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
}
else if (uwsgi.file_serve_mode == 2) {
wsgi_req->header_cnt = 2;
wsgi_req->header_cnt += 2;
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, "X-Sendfile: ", 12);
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, orig_document_root, orig_document_root_len);
if (orig_document_root[orig_document_root_len-1] != '/') {
@@ -1408,7 +1472,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
}
else {
wsgi_req->header_cnt = 1;
wsgi_req->header_cnt += 1;
set_http_date(st.st_mtime, http_last_modified);
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
wsgi_req->sendfile_fd = open(real_filename, O_RDONLY);
+18
View File
@@ -0,0 +1,18 @@
import sys
import os
import pyuwsgi
orig_args = sys.argv
orig_executable = sys.executable
orig_args.insert(0, orig_executable)
uwsgi_args = []
for arg in sys.argv[2:]:
uwsgi_args.append(arg)
#pyuwsgi.run('welcome.ini')
pyuwsgi.run(uwsgi_args)
# if you are here uWSGI has been reloaded
os.execv(orig_executable, orig_args)
+22
View File
@@ -0,0 +1,22 @@
import sys
import os
import pyuwsgi
orig_args = sys.argv
orig_executable = sys.executable
orig_args.insert(0, orig_executable)
uwsgi_args = []
uwsgi_args.append('--socket')
uwsgi_args.append(':3031')
#uwsgi_args.append('--master')
uwsgi_args.append('--module')
#uwsgi_args.append('welcome')
uwsgi_args.append('hello')
#pyuwsgi.run('welcome.ini')
pyuwsgi.run(uwsgi_args)
# if you are here uWSGI has been reloaded
os.execv(orig_executable, orig_args)
+24 -2
View File
@@ -1,8 +1,30 @@
#ifdef UWSGI_PCRE
#include "uwsgi.h"
#include <pcre.h>
void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra) {
const char *errstr;
int erroff;
*pattern = pcre_compile( (const char *)re, 0, &errstr, &erroff, NULL);
if (!*pattern) {
uwsgi_log("pcre error: %s at offset %d\n", errstr, erroff);
exit(1);
}
*pattern_extra = (pcre_extra *) pcre_study((const pcre*)*pattern, 0, &errstr);
if (!*pattern_extra) {
uwsgi_log("pcre (study) error: %s\n", errstr);
exit(1);
}
}
int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length) {
return pcre_exec((const pcre*)pattern, (const pcre_extra *)pattern_extra, subject, length, 0, 0, NULL, 0 );
}
/*
+5 -3
View File
@@ -56,9 +56,11 @@ ssize_t uwsgi_do_sendfile(int sockfd, int filefd, size_t filesize, size_t chunk,
sf_ret = sendfile(filefd, sockfd, 0, 0, NULL, &sf_len, 0);
}
if (sf_ret) {
uwsgi_error("sendfile()");
return 0;
if (sf_ret < 0) {
if (errno != EAGAIN) {
uwsgi_error("sendfile()");
return 0;
}
}
return sf_len;
+10 -4
View File
@@ -6,6 +6,7 @@ import shutil
from setuptools import setup
from setuptools.dist import Distribution
from setuptools.command.install import install
from setuptools.command.install_lib import install_lib
from setuptools.command.build_ext import build_ext
def get_profile():
@@ -42,22 +43,27 @@ class uWSGIBuilder(build_ext):
class uWSGIInstall(install):
def run(self):
# hack, hack and still hack. We need to find a solution...
if self.record:
record_file = open(self.record,'w')
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
install.run(self)
class uWSGIInstallLib(install_lib):
def run(self):
conf = uc.uConf(get_profile())
patch_bin_path(self, conf)
uc.build_uwsgi( conf )
class uWSGIDistribution(Distribution):
def __init__(self, *attrs):
Distribution.__init__(self, *attrs)
self.cmdclass['install'] = uWSGIInstall
self.cmdclass['install_lib'] = uWSGIInstallLib
self.cmdclass['build_ext'] = uWSGIBuilder
setup(name='uWSGI',
version=uc.uwsgi_version,
description='The uWSGI server',
+79 -3
View File
@@ -12,7 +12,55 @@ int uwsgi_signal_handler(uint8_t sig) {
return -1;
}
return uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
// set harakiri here (if required and if i am a worker)
if (uwsgi.mywid > 0) {
uwsgi.workers[uwsgi.mywid].sig = 1;
uwsgi.workers[uwsgi.mywid].signum = sig;
uwsgi.workers[uwsgi.mywid].signals++;
if(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
}
}
else if (uwsgi.muleid > 0) {
uwsgi.mules[uwsgi.muleid-1].sig = 1;
uwsgi.mules[uwsgi.muleid-1].signum = sig;
uwsgi.mules[uwsgi.muleid-1].signals++;
if(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI] > 0) {
set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]);
}
}
#ifdef UWSGI_SPOOLER
else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) {
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
}
}
#endif
int ret = uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
if (uwsgi.mywid > 0) {
uwsgi.workers[uwsgi.mywid].sig = 0;
if(uwsgi.workers[uwsgi.mywid].harakiri > 0) {
set_harakiri(0);
}
}
else if (uwsgi.muleid > 0) {
uwsgi.mules[uwsgi.muleid-1].sig = 0;
if(uwsgi.mules[uwsgi.muleid-1].harakiri > 0) {
set_mule_harakiri(0);
}
}
#ifdef UWSGI_SPOOLER
else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) {
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(0);
}
}
#endif
return ret;
}
int uwsgi_signal_registered(uint8_t sig) {
@@ -166,7 +214,7 @@ void uwsgi_route_signal(uint8_t sig) {
// send to all workers
else if (!strcmp(use->receiver, "workers")) {
for(i=1;i<=uwsgi.numproc;i++) {
if (write(uwsgi.signal_pipe[i][0], &sig, 1) != 1) {
if (write(uwsgi.workers[i].signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
}
@@ -178,7 +226,7 @@ void uwsgi_route_signal(uint8_t sig) {
if (i > uwsgi.numproc) {
uwsgi_log("invalid signal target: %s\n", use->receiver);
}
if (write(uwsgi.signal_pipe[i][0], &sig, 1) != 1) {
if (write(uwsgi.workers[i].signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
uwsgi_log("could not deliver signal %d to worker %d\n", sig, i);
}
@@ -187,6 +235,7 @@ void uwsgi_route_signal(uint8_t sig) {
else if (!strcmp(use->receiver, "subscribed")) {
}
// route to spooler
#ifdef UWSGI_SPOOLER
else if (!strcmp(use->receiver, "spooler")) {
if (ushared->worker_signal_pipe[0] != -1) {
if (write(ushared->spooler_signal_pipe[0], &sig, 1) != 1) {
@@ -195,6 +244,33 @@ void uwsgi_route_signal(uint8_t sig) {
}
}
}
#endif
else if (!strcmp(use->receiver, "mules")) {
for(i=0;i<uwsgi.mules_cnt;i++) {
if (write(uwsgi.mules[i].signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i+1);
}
}
}
else if (!strncmp(use->receiver, "mule", 4)) {
i = atoi(use->receiver+4);
if (i > uwsgi.mules_cnt) {
uwsgi_log("invalid signal target: %s\n", use->receiver);
}
else if (i == 0) {
if (write(ushared->mule_signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
uwsgi_log("could not deliver signal %d to a mule\n", sig);
}
}
else {
if (write(uwsgi.mules[i-1].signal_pipe[0], &sig, 1) != 1) {
uwsgi_error("write()");
uwsgi_log("could not deliver signal %d to mule %d\n", sig, i);
}
}
}
else {
// unregistered signal, sending it to all the workers
uwsgi_log("^^^ UNSUPPORTED SIGNAL TARGET: %s ^^^\n", use->receiver);
+44 -1
View File
@@ -474,7 +474,13 @@ socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *s
sin_addr->sin_addr.s_addr = INADDR_ANY;
}
else {
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
char *resolved = uwsgi_resolve_ip(socket_name);
if (resolved) {
sin_addr->sin_addr.s_addr = inet_addr(resolved);
}
else {
sin_addr->sin_addr.s_addr = inet_addr(socket_name);
}
}
return sizeof(struct sockaddr_in);
@@ -749,6 +755,20 @@ struct uwsgi_socket *uwsgi_new_socket(char *name) {
if (!name) return uwsgi_sock;
if (name[0] == '=') {
int shared_socket = atoi(uwsgi_sock->name+1);
if (shared_socket >= 0) {
struct uwsgi_socket *uss = uwsgi_get_shared_socket_by_num(shared_socket);
if (!uss) {
uwsgi_log("unable to use shared socket %d\n", shared_socket);
exit(1);
}
uwsgi_sock->bound = 1;
uwsgi_sock->shared = 1;
uwsgi_sock->from_shared = shared_socket;
return uwsgi_sock;
}
}
char *tcp_port = strchr(name, ':');
if (tcp_port) {
// INET socket, check for 0 port
@@ -951,6 +971,29 @@ int uwsgi_get_shared_socket_fd_by_num(int num) {
return -1;
}
struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int num) {
int counter = 0;
struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.shared_sockets;
while(uwsgi_sock) {
if (counter == num) {
found_sock = uwsgi_sock;
break;
}
counter++;
uwsgi_sock = uwsgi_sock->next;
}
if (found_sock) {
return found_sock;
}
return NULL;
}
void uwsgi_add_sockets_to_queue(int queue) {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
+33 -25
View File
@@ -16,18 +16,7 @@ pid_t spooler_start() {
int i;
if (uwsgi.master_process) {
if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]);
if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]);
// setup internal signalling system
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.shared->spooler_signal_pipe)) {
uwsgi_error("socketpair()\n");
exit(1);
}
}
pid_t pid = fork();
pid_t pid = uwsgi_fork("uWSGI spooler");
if (pid < 0) {
uwsgi_error("fork()");
exit(1);
@@ -36,23 +25,21 @@ pid_t spooler_start() {
// USR1 will be used to wake up the spooler
signal(SIGUSR1, spooler_wakeup);
uwsgi.mywid = -1;
uwsgi.mypid = pid;
uwsgi.mypid = getpid();
// avoid race conditions !!!
uwsgi.shared->spooler_pid = uwsgi.mypid;
uwsgi_fixup_fds(0, 0);
uwsgi_close_all_sockets();
if (uwsgi.master_process) {
close(uwsgi.shared->spooler_signal_pipe[0]);
for(i=1;i<=uwsgi.numproc;i++) {
if (uwsgi.signal_pipe[i][0] != -1) {
close(uwsgi.signal_pipe[i][0]);
}
}
}
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->post_fork) {
uwsgi.p[i]->post_fork();
}
}
uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1];
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->spooler_init) {
uwsgi.p[i]->spooler_init();
@@ -64,12 +51,10 @@ pid_t spooler_start() {
uwsgi.gp[i]->spooler_init();
}
}
spooler();
}
else if (pid > 0) {
if (uwsgi.master_process) {
close(uwsgi.shared->spooler_signal_pipe[1]);
}
uwsgi_log("spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid);
}
@@ -251,6 +236,8 @@ void spooler() {
if (uwsgi.spooler_ordered) {
#ifdef __linux__
spooler_scandir(uwsgi.spool_dir);
#else
spooler_readdir(uwsgi.spool_dir);
#endif
}
else {
@@ -362,7 +349,12 @@ void spooler_manage_task(char *dir, char *task) {
if (!access(task, R_OK | W_OK)) {
uwsgi_log("managing spool request %s ...\n", task);
#ifdef __sun__
// lockf needs write permission
spool_fd = open(task, O_RDWR);
#else
spool_fd = open(task, O_RDONLY);
#endif
if (spool_fd < 0) {
uwsgi_error_open(task);
return;
@@ -411,16 +403,29 @@ void spooler_manage_task(char *dir, char *task) {
close(spool_fd);
if (uwsgi.spooler_chdir) {
if (chdir(uwsgi.spooler_chdir)) {
uwsgi_error("chdir()");
}
}
int callable_found = 0;
for(i=0;i<0xff;i++) {
if (uwsgi.p[i]->spooler) {
time_t now = time(NULL);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
}
ret = uwsgi.p[i]->spooler(task, spool_buf, uh.pktsize, body, body_len);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(0);
}
if (body) {
free(body);
}
if (ret == 0) continue;
callable_found = 1;
if (ret == -2) {
uwsgi_log("done with task/spool %s after %d seconds\n", task, time(NULL)-now);
destroy_spool(dir, task);
}
@@ -428,6 +433,9 @@ void spooler_manage_task(char *dir, char *task) {
break;
}
}
if (!callable_found) {
uwsgi_log("unable to find the spooler function, have you loaded it into the spooler process ?\n");
}
}
}
+24 -1
View File
@@ -1,17 +1,39 @@
import gevent
import gevent.socket
import sys
import uwsgi
from uwsgidecorators import *
if 'gettotalrefcount' in sys.__dict__:
REFCNT = True
else:
REFCNT = False
@signal(17)
def hello(signum):
print "hello i am signal %d, i am here because the background job is finished" % signum
if REFCNT:
print sys.gettotalrefcount()
@timer(10)
def ten_seconds(signum):
print "10 seconds elapsed, signal %d raised" % signum
if REFCNT:
print sys.gettotalrefcount()
@filemon('/tmp')
def tmp_modified(signum):
print "/tmp has been touched, i am the greenlet %s running on worker %d" % (gevent.getcurrent(), uwsgi.worker_id())
if REFCNT:
print sys.gettotalrefcount()
def bg_task():
for i in range(1,10):
print "background task", i
gevent.sleep(2)
gevent.sleep(1)
# task ended raise a signal !!!
uwsgi.signal(17)
def long_task():
for i in range(1,10):
@@ -43,6 +65,7 @@ def application(e, sr):
if REFCNT:
print sys.gettotalrefcount()
yield "%d" % sys.gettotalrefcount()
# this task will goes on after request end
gevent.spawn(bg_task)
+5
View File
@@ -0,0 +1,5 @@
import uwsgi
print(uwsgi.opt)
print(uwsgi.magic_table)
from werkzeug.testapp import test_app as application
+48 -2
View File
@@ -1,5 +1,19 @@
import uuid
import uwsgi
import os
def application(env, start_response):
if env['PATH_INFO'].startswith('/progress/'):
start_response('200 Ok', [('Content-type', 'application/json')])
filename = 'foobar/' + env['PATH_INFO'][10:]
print filename
if os.path.exists(filename):
return uwsgi.sendfile(filename)
else:
return "{ 'state': 'done' }"
if env['REQUEST_METHOD'] == 'POST':
start_response('200 Ok', [('Content-type', 'text/plain')])
@@ -14,12 +28,44 @@ def application(env, start_response):
return body
else:
start_response('200 Ok', [('Content-type', 'text/html')])
x_progress_id = str(uuid.uuid4())
return """
<form method="POST" enctype="multipart/form-data">
<html>
<head>
<script src="/static/jquery-1.5.1.min.js" /></script>
<script language="Javascript">
var interval;
function redrawProgressBar() {
interval = setInterval(getData, 1000);
}
function getData() {
var jsr = $.getJSON("/progress/%s.js",
function(data) {
if (data) {
if (data.state == 'uploading') {
$('#progress').html(data.received + '/' + data.size);
return;
}
}
alert("fine");
clearInterval(interval);
}
);
jsr.error(function() { clearInterval(interval); });
}
</script>
</head>
<body>
upload progress: <div id="progress"> 0%%</div>
<form method="POST" enctype="multipart/form-data" action="?X-Progress-ID=%s" onsubmit="redrawProgressBar(); return true;">
<textarea name="pluto">
</textarea>
<input type="file" name="pippo" />
<input type="submit" value="invia" />
</form>
"""
</body>
</html>
""" % (x_progress_id, x_progress_id)
+692 -59
View File
@@ -2,6 +2,7 @@
extern struct uwsgi_server uwsgi;
extern char **environ;
/* statistically ordered */
struct http_status_codes hsc[] = {
@@ -98,19 +99,44 @@ void inc_harakiri(int sec) {
}
void set_harakiri(int sec) {
if (uwsgi.master_process) {
if (sec == 0) {
uwsgi.workers[uwsgi.mywid].harakiri = 0;
}
else {
uwsgi.workers[uwsgi.mywid].harakiri = time(NULL) + sec;
}
if (sec == 0) {
uwsgi.workers[uwsgi.mywid].harakiri = 0;
}
else {
uwsgi.workers[uwsgi.mywid].harakiri = time(NULL) + sec;
}
if (!uwsgi.master_process) {
alarm(sec);
}
}
void set_mule_harakiri(int sec) {
if (sec == 0) {
uwsgi.mules[uwsgi.muleid-1].harakiri = 0;
}
else {
uwsgi.mules[uwsgi.muleid-1].harakiri = time(NULL) + sec;
}
if (!uwsgi.master_process) {
alarm(sec);
}
}
#ifdef UWSGI_SPOOLER
void set_spooler_harakiri(int sec) {
if (sec == 0) {
uwsgi.shared->spooler_harakiri = 0;
}
else {
uwsgi.shared->spooler_harakiri = time(NULL) + sec;
}
if (!uwsgi.master_process) {
alarm(sec);
}
}
#endif
void daemonize(char *logfile) {
pid_t pid;
int fdin;
@@ -195,7 +221,13 @@ void logto(char *logfile) {
udp_addr.sin_family = AF_INET;
udp_addr.sin_port = htons(atoi(udp_port + 1));
udp_addr.sin_addr.s_addr = inet_addr(logfile);
char *resolved = uwsgi_resolve_ip(logfile);
if (resolved) {
udp_addr.sin_addr.s_addr = inet_addr(resolved);
}
else {
udp_addr.sin_addr.s_addr = inet_addr(logfile);
}
if (connect(fd, (const struct sockaddr *) &udp_addr, sizeof(struct sockaddr_in)) < 0) {
uwsgi_error("connect()");
@@ -204,7 +236,12 @@ void logto(char *logfile) {
}
else {
#endif
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
if (uwsgi.log_truncate) {
fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP);
}
else {
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
}
if (fd < 0) {
uwsgi_error_open(logfile);
exit(1);
@@ -360,6 +397,8 @@ void create_logpipe(void) {
void log_syslog(char *syslog_opts) {
setlinebuf(stderr);
if (syslog_opts == NULL) {
syslog_opts = "uwsgi";
}
@@ -433,13 +472,13 @@ void log_syslog(char *syslog_opts) {
char *uwsgi_get_cwd() {
int newsize = 256;
char *cwd;
// set this to static to avoid useless reallocations in stats mode
static size_t newsize = 256;
cwd = uwsgi_malloc(newsize);
char *cwd = uwsgi_malloc(newsize);
if (getcwd(cwd, newsize) == NULL) {
newsize = errno;
if (getcwd(cwd, newsize) == NULL && errno == ERANGE) {
newsize += 256;
uwsgi_log("need a bigger buffer (%d bytes) for getcwd(). doing reallocation.\n", newsize);
free(cwd);
cwd = uwsgi_malloc(newsize);
@@ -552,6 +591,41 @@ void uwsgi_as_root() {
uwsgi_log("uWSGI running as root, you can use --uid/--gid/--chroot options\n");
}
#ifdef UWSGI_CAP
if (uwsgi.cap && uwsgi.cap_count > 0 && !uwsgi.reloads) {
cap_value_t minimal_cap_values[] = { CAP_SYS_CHROOT, CAP_SETUID, CAP_SETGID, CAP_SETPCAP };
cap_t caps = cap_init();
if (!caps) {
uwsgi_error("cap_init()");
exit(1);
}
cap_clear(caps);
cap_set_flag(caps, CAP_EFFECTIVE, 4, minimal_cap_values, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, 4, minimal_cap_values, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, uwsgi.cap_count, uwsgi.cap, CAP_SET);
cap_set_flag(caps, CAP_INHERITABLE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
if (cap_set_proc(caps) < 0) {
uwsgi_error("cap_set_proc()");
exit(1);
}
cap_free(caps);
#ifdef __linux__
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
uwsgi_error("prctl()");
exit(1);
}
#endif
}
#endif
if (uwsgi.chroot && !uwsgi.reloads) {
if (!uwsgi.master_as_root)
uwsgi_log("chroot() to %s\n", uwsgi.chroot);
@@ -615,8 +689,32 @@ void uwsgi_as_root() {
}
if (!getuid()) {
uwsgi_log(" *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n");
uwsgi_log("*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n");
}
#ifdef UWSGI_CAP
if (uwsgi.cap && uwsgi.cap_count > 0 && !uwsgi.reloads) {
cap_t caps = cap_init();
if (!caps) {
uwsgi_error("cap_init()");
exit(1);
}
cap_clear(caps);
cap_set_flag(caps, CAP_EFFECTIVE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, uwsgi.cap_count, uwsgi.cap, CAP_SET);
cap_set_flag(caps, CAP_INHERITABLE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
if (cap_set_proc(caps) < 0) {
uwsgi_error("cap_set_proc()");
exit(1);
}
cap_free(caps);
}
#endif
}
else {
if (uwsgi.chroot && !uwsgi.is_a_reload) {
@@ -655,13 +753,17 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
int waitpid_status;
int tmp_id;
uint64_t tmp_rt;
gettimeofday(&wsgi_req->end_of_request, NULL);
//uwsgi.workers[uwsgi.mywid].running_time += (double) (((double) (wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec) - (double) (wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec)) / (double) 1000.0);
tmp_rt = (wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec) - (wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec);
uwsgi.workers[uwsgi.mywid].running_time += tmp_rt;
uwsgi.workers[uwsgi.mywid].avg_response_time = (uwsgi.workers[uwsgi.mywid].avg_response_time+tmp_rt)/2;
// get memory usage
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.reload_on_as || uwsgi.reload_on_rss)
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.force_get_memusage )
get_memusage();
@@ -685,10 +787,18 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
#endif
// leave harakiri mode
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
if (uwsgi.workers[uwsgi.mywid].harakiri > 0) {
set_harakiri(0);
}
// this is racy in multithread mode
if (wsgi_req->response_size > 0) {
uwsgi.workers[uwsgi.mywid].tx += wsgi_req->response_size;
}
if (wsgi_req->headers_size > 0) {
uwsgi.workers[uwsgi.mywid].tx += wsgi_req->headers_size;
}
// defunct process reaper
if (uwsgi.shared->options[UWSGI_OPTION_REAPER] == 1 || uwsgi.grunt) {
while (waitpid(WAIT_ANY, &waitpid_status, WNOHANG) > 0);
@@ -703,11 +813,11 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
goodbye_cruel_world();
}
if (uwsgi.reload_on_as && (int) (uwsgi.workers[uwsgi.mywid].vsz_size / 1024 / 1024) >= uwsgi.reload_on_as) {
if (uwsgi.reload_on_as && (rlim_t) uwsgi.workers[uwsgi.mywid].vsz_size >= uwsgi.reload_on_as) {
goodbye_cruel_world();
}
if (uwsgi.reload_on_rss && (int) (uwsgi.workers[uwsgi.mywid].rss_size / 1024 / 1024) >= uwsgi.reload_on_rss) {
if (uwsgi.reload_on_rss && (rlim_t) uwsgi.workers[uwsgi.mywid].rss_size >= uwsgi.reload_on_rss) {
goodbye_cruel_world();
}
@@ -751,12 +861,14 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_so
}
uwsgi.core[wsgi_req->async_id]->in_request = 0;
uwsgi.workers[uwsgi.mywid].busy = 0;
}
#ifdef UWSGI_ASYNC
int wsgi_req_async_recv(struct wsgi_request *wsgi_req) {
uwsgi.core[wsgi_req->async_id]->in_request = 1;
uwsgi.workers[uwsgi.mywid].busy = 1;
gettimeofday(&wsgi_req->start_of_request, NULL);
@@ -782,6 +894,7 @@ int wsgi_req_async_recv(struct wsgi_request *wsgi_req) {
int wsgi_req_recv(struct wsgi_request *wsgi_req) {
uwsgi.core[wsgi_req->async_id]->in_request = 1;
uwsgi.workers[uwsgi.mywid].busy = 1;
gettimeofday(&wsgi_req->start_of_request, NULL);
@@ -1343,15 +1456,31 @@ int uwsgi_get_app_id(char *app_name, int app_name_len, int modifier1) {
int i;
struct stat st;
int found;
for (i = 0; i < uwsgi_apps_cnt; i++) {
// reset check
found = 0;
#ifdef UWSGI_DEBUG
uwsgi_log("searching for %.*s in %.*s %p\n", app_name_len, app_name, uwsgi_apps[i].mountpoint_len, uwsgi_apps[i].mountpoint, uwsgi_apps[i].callable);
#endif
if (!uwsgi_apps[i].callable) {
continue;
}
#ifdef UWSGI_PCRE
if (uwsgi_apps[i].pattern) {
if (uwsgi_regexp_match(uwsgi_apps[i].pattern, uwsgi_apps[i].pattern_extra, app_name, app_name_len) >= 0) {
found = 1;
}
}
else
#endif
if (!uwsgi_strncmp(uwsgi_apps[i].mountpoint, uwsgi_apps[i].mountpoint_len, app_name, app_name_len)) {
found = 1;
}
if (found) {
if (uwsgi_apps[i].touch_reload) {
if (!stat(uwsgi_apps[i].touch_reload, &st)) {
if (st.st_mtime != uwsgi_apps[i].touch_reload_mtime) {
@@ -1507,18 +1636,18 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
}
// manage buffered data and upload progress
while (post_remains > 0) {
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
}
ret = poll(&wsgi_req->poll, 1, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] * 1000);
ret = uwsgi_waitfd(wsgi_req->poll.fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
if (ret < 0) {
uwsgi_error("poll()");
goto end;
return 0;
}
if (!ret) {
uwsgi_log("buffering POST data timedout !!!\n");
uwsgi_log("buffering POST data timed-out !!!\n");
goto end;
}
@@ -1543,7 +1672,7 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
goto end;
}
// resue buf for json buffer
// reuse buf for json buffer
ret = snprintf(buf, len, "{ \"state\" : \"uploading\", \"received\" : %d, \"size\" : %d }\r\n", (int) (wsgi_req->post_cl - post_remains), (int) wsgi_req->post_cl);
if (ret < 0) {
uwsgi_log("unable to write JSON data in upload progress file %s\n", upload_progress_filename);
@@ -1583,24 +1712,45 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
return 0;
}
void add_exported_option(char *key, char *value, int configured) {
void _add_exported_option(char *key, char *value, int configured) {
if (!uwsgi.exported_opts) {
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt *));
}
else {
uwsgi.exported_opts = realloc(uwsgi.exported_opts, sizeof(struct uwsgi_opt *) * (uwsgi.exported_opts_cnt + 1));
if (!uwsgi.exported_opts) {
uwsgi_error("realloc()");
exit(1);
}
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt *));
}
else {
uwsgi.exported_opts = realloc(uwsgi.exported_opts, sizeof(struct uwsgi_opt *) * (uwsgi.exported_opts_cnt + 1));
if (!uwsgi.exported_opts) {
uwsgi_error("realloc()");
exit(1);
}
}
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
uwsgi.exported_opts_cnt++;
}
void add_exported_option(char *key, char *value, int configured) {
char *v = value;
if (value && strchr(value, ';')) {
v = uwsgi_str(value);
}
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
uwsgi.exported_opts_cnt++;
if (v == NULL) {
_add_exported_option(key, v, configured);
return;
}
char *p = strtok(v, ";");
while(p != NULL) {
_add_exported_option(key, p, configured);
p = strtok(NULL, ";");
}
}
@@ -1692,6 +1842,32 @@ int uwsgi_file_exists(char *filename) {
return !access(filename, R_OK);
}
char *uwsgi_read_fd(int fd, int *size, int add_zero) {
char stack_buf[4096];
ssize_t len;
char *buffer = NULL;
len = 1;
while(len > 0) {
len = read(fd, stack_buf, 4096);
if (len > 0) {
*size += len;
buffer = realloc(buffer, *size);
memcpy(buffer+(*size-len), stack_buf, len);
}
}
if (add_zero) {
*size = *size+1;
buffer = realloc(buffer, *size);
buffer[*size-1] = 0;
}
return buffer;
}
char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[]) {
int fd;
@@ -1707,23 +1883,12 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
// stdin ?
if (!strcmp(url, "-")) {
char stack_buf[4096];
len = 1;
while(len > 0) {
len = read(0, stack_buf, 4096);
if (len > 0) {
*size += len;
buffer = realloc(buffer, *size);
memcpy(buffer+(*size-len), stack_buf, len);
}
}
if (add_zero) {
*size = *size+1;
buffer = realloc(buffer, *size);
buffer[*size-1] = 0;
}
buffer = uwsgi_read_fd(0, size, add_zero);
}
// fd ?
else if (!strncmp("fd://", url, 5)) {
fd = atoi(url+5);
buffer = uwsgi_read_fd(fd, size, add_zero);
}
// http url ?
else if (!strncmp("http://", url, 7)) {
@@ -1966,6 +2131,10 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
exit(1);
}
if (S_ISFIFO(sb.st_mode)) {
buffer = uwsgi_read_fd(fd, size, add_zero);
goto end;
}
buffer = malloc(sb.st_size + add_zero);
@@ -1989,6 +2158,8 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
buffer[sb.st_size] = 0;
}
end:
if (magic_table) {
magic_buf = magic_sub(buffer, *size, size, magic_table);
@@ -2090,8 +2261,13 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
char *a;
int cnt = 1;
int devnull = -1;
int throttle = 0;
pid_t pid = fork();
if (uwsgi.current_time - ud->last_spawn <= 3) {
throttle = ud->respawns - (uwsgi.current_time-ud->last_spawn);
}
pid_t pid = uwsgi_fork("uWSGI external daemon");
if (pid < 0) {
uwsgi_error("fork()");
return;
@@ -2154,6 +2330,12 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
argv[cnt] = NULL;
if (throttle) {
uwsgi_log_verbose("throttling %s for %d seconds\n", argv[0], throttle);
sleep(throttle);
}
uwsgi_log_verbose("running %s\n", argv[0]);
if (execvp(argv[0], argv)) {
uwsgi_error("execvp()");
}
@@ -2282,6 +2464,37 @@ int uwsgi_list_has_str(char *list, char *str) {
return 0;
}
char hex2num(char *str) {
char val = 0;
val <<= 4;
if (str[0] >= '0' && str[0] <= '9') {
val += str[0] & 0x0F;
}
else if ( str[0] >= 'A' && str[0] <= 'F') {
val += (str[0] & 0x0F) + 9;
}
else {
return 0;
}
val <<= 4;
if (str[1] >= '0' && str[1] <= '9') {
val += str[1] & 0x0F;
}
else if ( str[1] >= 'A' && str[1] <= 'F') {
val += (str[1] & 0x0F) + 9;
}
else {
return 0;
}
return val;
}
int uwsgi_str2_num(char *str) {
int num = 0;
@@ -2438,6 +2651,37 @@ char *uwsgi_netstring(char *buf, size_t len, char **netstring, size_t *netstring
return NULL;
}
struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **dd, char *key, int keylen, char *val, int vallen) {
struct uwsgi_dyn_dict *uwsgi_dd = *dd, *old_dd;
if (!uwsgi_dd) {
*dd = uwsgi_malloc(sizeof(struct uwsgi_dyn_dict));
uwsgi_dd = *dd;
uwsgi_dd->prev = NULL;
}
else {
while(uwsgi_dd) {
old_dd = uwsgi_dd;
uwsgi_dd = uwsgi_dd->next;
}
uwsgi_dd = uwsgi_malloc(sizeof(struct uwsgi_dyn_dict));
old_dd->next = uwsgi_dd;
uwsgi_dd->prev = old_dd;
}
uwsgi_dd->key = key;
uwsgi_dd->keylen = keylen;
uwsgi_dd->value = val;
uwsgi_dd->vallen = vallen;
uwsgi_dd->hits = 0;
uwsgi_dd->next = NULL;
return uwsgi_dd;
}
struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list, char *value) {
struct uwsgi_string_list *uwsgi_string = *list, *old_uwsgi_string;
@@ -2457,12 +2701,34 @@ struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list,
}
uwsgi_string->value = value;
uwsgi_string->len = strlen(value);
uwsgi_string->len = 0;
if (value) {
uwsgi_string->len = strlen(value);
}
uwsgi_string->next = NULL;
return uwsgi_string;
}
char *uwsgi_string_get_list(struct uwsgi_string_list **list, int pos, size_t *len) {
struct uwsgi_string_list *uwsgi_string = *list;
int counter = 0;
while(uwsgi_string) {
if (counter == pos) {
*len = uwsgi_string->len;
return uwsgi_string->value;
}
uwsgi_string = uwsgi_string->next;
counter++;
}
*len = 0;
return NULL;
}
void uwsgi_string_del_list(struct uwsgi_string_list **list, struct uwsgi_string_list *item) {
@@ -2721,14 +2987,15 @@ char *uwsgi_get_binary_path(char *argvzero) {
}
free(buf);
#elif defined(__sun__)
// do not free this value !!!
char *buf = (char *)getexecname();
if (buf) {
// return only absolute path
if (buf[0] == '/') {
return buf;
}
char *newbuf = realpath(buf, NULL);
free(buf);
if (newbuf) {
return newbuf;
}
@@ -2751,3 +3018,369 @@ char *uwsgi_get_binary_path(char *argvzero) {
return argvzero;
}
char *uwsgi_get_line(char *ptr, char *watermark, int *size) {
char *p = ptr;
int count = 0;
while(p < watermark) {
if (*p == '\n') {
*size = count;
return ptr+count;
}
count++;
p++;
}
return NULL;
}
void uwsgi_build_mime_dict(char *filename) {
int size = 0;
char *buf = uwsgi_open_and_read(filename, &size, 1, NULL);
char *watermark = buf+size;
int linesize = 0;
char *line = buf;
int i;
int type_size = 0;
int ext_start = 0;
int found ;
int entries = 0;
uwsgi_log("building mime-types dictionary from file %s...", filename);
while(uwsgi_get_line(line, watermark, &linesize) != NULL) {
found = 0;
if (isalnum((int)line[0])) {
// get the type size
for(i=0;i<linesize;i++) {
if (isblank((int)line[i])) {
type_size = i;
found = 1;
break;
}
}
if (!found) { line += linesize+1; continue;}
found = 0;
for(i=type_size;i<linesize;i++) {
if (!isblank((int)line[i])) {
ext_start = i;
found = 1;
break;
}
}
if (!found) { line += linesize+1; continue;}
char *current = line+ext_start;
int ext_size = 0;
for(i=ext_start;i<linesize;i++) {
if (isblank((int)line[i])) {
#ifdef UWSGI_DEBUG
uwsgi_log("%.*s %.*s\n", ext_size, current, type_size, line);
#endif
uwsgi_dyn_dict_new(&uwsgi.mimetypes, current, ext_size, line, type_size);
entries++;
ext_size = 0;
current = NULL;
continue;
}
else if (current == NULL) {
current = line+i;
}
ext_size++;
}
if (current && ext_size > 1) {
#ifdef UWSGI_DEBUG
uwsgi_log("%.*s %.*s\n", ext_size, current, type_size, line);
#endif
uwsgi_dyn_dict_new(&uwsgi.mimetypes, current, ext_size, line, type_size);
entries++;
}
}
line += linesize+1;
}
uwsgi_log("%d entry found\n", entries);
}
#ifdef UWSGI_CAP
struct uwsgi_cap {
char *name;
cap_value_t value;
};
static struct uwsgi_cap uwsgi_cap_list[] = {
{ "chown", CAP_CHOWN},
{ "dac_override", CAP_DAC_OVERRIDE},
{ "dac_read_search", CAP_DAC_READ_SEARCH},
{ "fowner", CAP_FOWNER},
{ "fsetid", CAP_FSETID},
{ "kill", CAP_KILL},
{ "setgid", CAP_SETGID},
{ "setuid", CAP_SETUID},
{ "setpcap", CAP_SETPCAP},
{ "linux_immutable", CAP_LINUX_IMMUTABLE},
{ "net_bind_service", CAP_NET_BIND_SERVICE},
{ "net_broadcast", CAP_NET_BROADCAST},
{ "net_admin", CAP_NET_ADMIN},
{ "net_raw", CAP_NET_RAW},
{ "ipc_lock", CAP_IPC_LOCK},
{ "ipc_owner", CAP_IPC_OWNER},
{ "sys_module", CAP_SYS_MODULE},
{ "sys_rawio", CAP_SYS_RAWIO},
{ "sys_chroot", CAP_SYS_CHROOT},
{ "sys_ptrace", CAP_SYS_PTRACE},
{ "sys_pacct", CAP_SYS_PACCT},
{ "sys_admin", CAP_SYS_ADMIN},
{ "sys_boot", CAP_SYS_BOOT},
{ "sys_nice", CAP_SYS_NICE},
{ "sys_resource", CAP_SYS_RESOURCE},
{ "sys_time", CAP_SYS_TIME},
{ "sys_tty_config", CAP_SYS_TTY_CONFIG},
{ "mknod", CAP_MKNOD},
{ "lease", CAP_LEASE},
{ "audit_write", CAP_AUDIT_WRITE},
{ "audit_control", CAP_AUDIT_CONTROL},
{ "setfcap", CAP_SETFCAP},
{ "mac_override", CAP_MAC_OVERRIDE},
{ "mac_admin", CAP_MAC_ADMIN},
{ "syslog", CAP_SYSLOG},
{ "wake_alarm", CAP_WAKE_ALARM},
{ NULL, -1}
};
static int uwsgi_get_cap_id(char *name) {
struct uwsgi_cap *ucl = uwsgi_cap_list;
while(ucl->name) {
if (!strcmp(ucl->name, name)) return ucl->value;
ucl++;
}
return -1;
}
void uwsgi_build_cap(char *what) {
int cap_id;
char *caps = uwsgi_str(what);
int pos = 0;
uwsgi.cap_count = 0;
char *p = strtok(caps, ",");
while (p != NULL) {
if (is_a_number(p)) {
uwsgi.cap_count++;
}
else {
cap_id = uwsgi_get_cap_id(p);
if (cap_id != -1) {
uwsgi.cap_count++;
}
}
p = strtok(NULL, ",");
}
free(caps);
uwsgi.cap = uwsgi_malloc( sizeof(cap_value_t) * uwsgi.cap_count);
caps = uwsgi_str(what);
p = strtok(caps, ",");
while (p != NULL) {
if (is_a_number(p)) {
cap_id = atoi(p);
}
else {
cap_id = uwsgi_get_cap_id(p);
}
if (cap_id != -1) {
uwsgi.cap[pos] = cap_id;
uwsgi_log("setting capability %s [%d]\n", p, cap_id);
pos++;
}
p = strtok(NULL, ",");
}
free(caps);
}
#endif
void uwsgi_apply_config_pass(char symbol, char*(*hook)(char *) ) {
int i, j;
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
int has_symbol = 0;
char *magic_key = NULL;
char *magic_val = NULL;
if (uwsgi.exported_opts[i]->value && !uwsgi.exported_opts[i]->configured) {
for (j = 0; j < (int) strlen(uwsgi.exported_opts[i]->value); j++) {
if (uwsgi.exported_opts[i]->value[j] == symbol) {
has_symbol = 1;
}
else if (uwsgi.exported_opts[i]->value[j] == '(' && has_symbol == 1) {
has_symbol = 2;
magic_key = uwsgi.exported_opts[i]->value + j + 1;
}
else if (has_symbol > 1) {
if (uwsgi.exported_opts[i]->value[j] == ')') {
if (has_symbol <= 2) {
magic_key = NULL;
has_symbol = 0;
continue;
}
#ifdef UWSGI_DEBUG
uwsgi_log("need to interpret the %.*s tag\n", has_symbol - 2, magic_key);
#endif
char *tmp_magic_key = uwsgi_concat2n(magic_key, has_symbol - 2, "", 0);
magic_val = hook(tmp_magic_key);
free(tmp_magic_key);
if (!magic_val) {
magic_key = NULL;
has_symbol = 0;
continue;
}
uwsgi.exported_opts[i]->value = uwsgi_concat4n(uwsgi.exported_opts[i]->value, (magic_key - 2) - uwsgi.exported_opts[i]->value, magic_val, strlen(magic_val), magic_key + (has_symbol - 1), strlen(magic_key + (has_symbol - 1)), "", 0);
#ifdef UWSGI_DEBUG
uwsgi_log("computed new value = %s\n", uwsgi.exported_opts[i]->value);
#endif
magic_key = NULL;
has_symbol = 0;
j = 0;
}
else {
has_symbol++;
}
}
else {
has_symbol = 0;
}
}
}
}
}
void uwsgi_set_processname(char *name) {
#if defined(__linux__) || defined(__sun__)
size_t amount = 0;
// prepare for strncat
*uwsgi.orig_argv[0] = 0;
if (uwsgi.procname_prefix) {
amount += strlen(uwsgi.procname_prefix);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], uwsgi.procname_prefix, uwsgi.max_procname-(amount+1));
}
amount += strlen(name);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], name, (uwsgi.max_procname-amount+1));
if (uwsgi.procname_append) {
amount += strlen(uwsgi.procname_append);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], uwsgi.procname_append, uwsgi.max_procname-(amount+1));
}
memset(uwsgi.orig_argv[0]+amount+1, ' ', uwsgi.max_procname-(amount-1));
#elif defined(__FreeBSD__)
if (uwsgi.procname_prefix) {
if (!uwsgi.procname_append) {
setproctitle("-%s%s", uwsgi.procname_prefix, name);
}
else {
setproctitle("-%s%s%s", uwsgi.procname_prefix, name, uwsgi.procname_append);
}
}
else if (uwsgi.procname_append) {
if (!uwsgi.procname_prefix) {
setproctitle("-%s%s", name, uwsgi.procname_append);
}
else {
setproctitle("-%s%s%s", uwsgi.procname_prefix, name, uwsgi.procname_append);
}
}
else {
setproctitle("-%s", name);
}
#endif
}
// this is a wrapper for fork restoring original argv
pid_t uwsgi_fork(char *name) {
pid_t pid = fork();
if (pid == 0) {
#if defined(__linux__) || defined(__sun__)
int i;
for(i=0;i<uwsgi.argc;i++) {
strcpy(uwsgi.orig_argv[i],uwsgi.argv[i]);
}
#endif
if (uwsgi.auto_procname && name) {
if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else {
uwsgi_set_processname(name);
}
}
}
return pid;
}
void http_url_decode(char *buf, uint16_t *len, char *dst) {
uint16_t i;
int percent = 0;
char value[2];
size_t new_len = 0;
char *ptr = dst;
value[0] = '0';
value[1] = '0';
for(i=0;i<*len;i++) {
if (buf[i] == '%') {
if (percent == 0) {
percent = 1;
}
else {
*ptr++= '%';
new_len++;
percent = 0;
}
}
else {
if (percent == 1) {
value[0] = buf[i];
percent = 2;
}
else if (percent == 2) {
value[1] = buf[i];
*ptr++= hex2num(value);
percent = 0;
new_len++;
}
else {
*ptr++= buf[i];
new_len++;
}
}
}
*len = new_len;
}
+528 -165
View File
File diff suppressed because it is too large Load Diff
+259 -15
View File
@@ -11,6 +11,8 @@ extern "C" {
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_fatal_error(x) uwsgi_error(x); exit(1);
#define uwsgi_error_open(x) uwsgi_log("open(\"%s\"): %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_req_error(x) if (wsgi_req->uri_len > 0 && wsgi_req->method_len > 0 && wsgi_req->remote_addr_len > 0) uwsgi_log_verbose("%s: %s [%s line %d] during %.*s %.*s (%.*s)\n", x, strerror(errno), __FILE__, __LINE__,\
wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr); else uwsgi_log_verbose("%s %s [%s line %d] \n",x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
#define uwsgi_rawlog(x) if (write(2, x, strlen(x)) != strlen(x)) uwsgi_error("write()")
#define uwsgi_str(x) uwsgi_concat2(x, "")
@@ -26,6 +28,8 @@ extern "C" {
#define thunder_lock if (uwsgi.threads > 1) {pthread_mutex_lock(&uwsgi.thunder_mutex);}
#define thunder_unlock if (uwsgi.threads > 1) {pthread_mutex_unlock(&uwsgi.thunder_mutex);}
#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5))
#define ushared uwsgi.shared
#define MAX_APPS 64
@@ -112,6 +116,9 @@ extern char UWSGI_EMBED_CONFIG_END;
#include <stdarg.h>
#include <errno.h>
#ifndef __USE_ISOC99
#define __USE_ISOC99
#endif
#include <ctype.h>
#include <sys/time.h>
#include <unistd.h>
@@ -145,10 +152,10 @@ extern char UWSGI_EMBED_CONFIG_END;
#include <sys/reg.h>
#endif
extern int pivot_root(const char *new_root, const char *put_old);
#else
#include <limits.h>
#endif
#include <limits.h>
#include <dirent.h>
#ifdef UWSGI_SCTP
@@ -222,6 +229,10 @@ extern int pivot_root(const char *new_root, const char *put_old);
#include <sys/event.h>
#endif
#ifdef UWSGI_CAP
#include <sys/capability.h>
#endif
#ifdef __HAIKU__
#include <kernel/OS.h>
#endif
@@ -278,9 +289,23 @@ struct uwsgi_string_list {
char *value;
size_t len;
uint64_t custom;
struct uwsgi_string_list *next;
};
struct uwsgi_dyn_dict {
char *key;
int keylen;
char *value;
int vallen;
uint64_t hits;
struct uwsgi_dyn_dict *prev;
struct uwsgi_dyn_dict *next;
};
union uwsgi_sockaddr {
struct sockaddr sa;
@@ -486,6 +511,27 @@ struct uwsgi_opt {
#define LONG_ARGS_FASTCGI_SOCKET 17133
#define LONG_ARGS_THREADS_STACKSIZE 17134
#define LONG_ARGS_EMPEROR_THROTTLE 17135
#define LONG_ARGS_STOP 17136
#define LONG_ARGS_RELOAD 17137
#define LONG_ARGS_REGEXP_MOUNT 17138
#define LONG_ARGS_MIMEFILE 17139
#define LONG_ARGS_CHEAPER 17140
#define LONG_ARGS_CAP 17141
#define LONG_ARGS_STATS 17142
#define LONG_ARGS_MULE 17143
#define LONG_ARGS_LOG_MAXSIZE 17144
#define LONG_ARGS_LOG_BACKUPNAME 17145
#define LONG_ARGS_EVIL_RELOAD_ON_AS 17146
#define LONG_ARGS_EVIL_RELOAD_ON_RSS 17147
#define LONG_ARGS_SPOOLER_HARAKIRI 17148
#define LONG_ARGS_MULE_HARAKIRI 17149
#define LONG_ARGS_EMPEROR_STATS 17150
#define LONG_ARGS_SPOOLER_CHDIR 17151
#define LONG_ARGS_LOCKS 17152
#define LONG_ARGS_PROCNAME_PREFIX 17153
#define LONG_ARGS_PROCNAME_APPEND 17154
#define LONG_ARGS_PROCNAME 17155
#define LONG_ARGS_PROCNAME_MASTER 17156
#define UWSGI_OK 0
@@ -524,6 +570,8 @@ struct uwsgi_opt {
#define UWSGI_OPTION_LOG_SENDFILE 14
#define UWSGI_OPTION_BACKLOG_STATUS 15
#define UWSGI_OPTION_BACKLOG_ERRORS 16
#define UWSGI_OPTION_SPOOLER_HARAKIRI 17
#define UWSGI_OPTION_MULE_HARAKIRI 18
#define UWSGI_MODIFIER_ADMIN_REQUEST 10
#define UWSGI_MODIFIER_SPOOL_REQUEST 17
@@ -582,6 +630,8 @@ struct uwsgi_socket {
int disabled;
struct uwsgi_socket *next;
int shared;
int from_shared;
};
struct uwsgi_server;
@@ -605,7 +655,7 @@ struct uwsgi_plugin {
void (*init_apps) (void);
void (*fixup) (void);
void (*master_fixup) (int);
int (*mount_app) (char *, char *);
int (*mount_app) (char *, char *, int);
int (*manage_udp) (char *, int, char *, int);
int (*manage_xml) (char *, char *);
void (*suspend) (struct wsgi_request *);
@@ -623,14 +673,22 @@ struct uwsgi_plugin {
int (*spooler) (char *, char *, uint16_t, char *, size_t);
uint16_t(*rpc) (void *, uint8_t, char **, char *);
uint16_t(*rpc) (void *, uint8_t, char **, char *);
void (*jail) (int (*)(void *), char **);
int (*mule)(char *);
struct uwsgi_help_item *help;
};
#ifdef UWSGI_PCRE
#include <pcre.h>
void uwsgi_regexp_build(char *re, pcre **pattern, pcre_extra **pattern_extra);
int uwsgi_regexp_match(pcre *pattern, pcre_extra *pattern_extra, char *subject, int length);
#endif
struct uwsgi_app {
@@ -639,6 +697,11 @@ struct uwsgi_app {
char *mountpoint;
int mountpoint_len;
#ifdef UWSGI_PCRE
pcre *pattern;
pcre_extra *pattern_extra;
#endif
void *interpreter;
void *callable;
@@ -673,6 +736,7 @@ struct uwsgi_app {
void *uwsgi_version;
void *uwsgi_node;
uint64_t avg_response_time;
};
@@ -763,6 +827,7 @@ struct wsgi_request {
char *path_info;
uint16_t path_info_len;
int path_info_pos;
char *script;
uint16_t script_len;
@@ -901,39 +966,81 @@ struct uwsgi_signal_rb_timer {
struct uwsgi_server {
// store the machine hostname
char hostname[256];
int hostname_len;
char **orig_argv;
char **argv;
int argc;
int max_procname;
int auto_procname;
char **environ;
char *procname_prefix;
char *procname_append;
char *procname_master;
char *procname;
// quiet startup
int no_initial_output;
// enable threads
int has_threads;
// default app id
int default_app;
char *logto2;
// autoload plugins
int autoload;
int snapshot;
// enable auto-snapshotting
int auto_snapshot;
pid_t restore_snapshot;
int respawn_workers;
unsigned int reloads;
// leave master running as root
int master_as_root;
// kill the stack on SIGTERM (instead of brutal reloading)
int die_on_term;
// disable fd passing on unix socket
int no_fd_passing;
// store the current time
time_t current_time;
uint64_t master_cycles;
int reuse_port;
// enable lazy mode
int lazy;
// enable cheap mode
int cheap;
// enable cheaper mode
int cheaper;
// minimal number of running workers in cheaper mode
int cheaper_count;
// enable idle mode
int idle;
// destroy the stack when idle
int die_on_idle;
// store the screen session
char *screen_session;
// true if run under the emperor
int has_emperor;
int emperor_fd;
int emperor_tyrant;
int emperor_fd_config;
int early_emperor;
int emperor_throttle;
@@ -941,50 +1048,77 @@ struct uwsgi_server {
pid_t emperor_pid;
int emperor_broodlord;
int emperor_broodlord_count;
char *emperor_stats;
int emperor_stats_fd;
struct uwsgi_config_template *vassals_templates;
// true if loyal to the emperor
int loyal;
// amqp support
char *emperor_amqp_vhost;
char *emperor_amqp_username;
char *emperor_amqp_password;
// emperor hook (still in development)
char *vassals_start_hook;
char *vassals_stop_hook;
struct uwsgi_string_list *additional_headers;
// maximum time to wait after a reload
time_t master_mercy;
// set cpu affinity
int cpu_affinity;
int reload_mercy;
// map reloads to death
int exit_on_reload;
// store options
int option_index;
struct option *long_options;
struct uwsgi_opt **exported_opts;
int exported_opts_cnt;
// dump the whole set of options
int dump_options;
// show ini representation of the current config
int show_config;
//base for all the requests(even on async mode)
struct wsgi_request **wsgi_requests;
struct wsgi_request *wsgi_req;
char *remap_modifier;
// enable zerg mode
int *zerg;
char *zerg_server;
int zerg_server_fd;
// security
char *chroot;
gid_t gid;
uid_t uid;
char *uidname;
char *gidname;
#ifdef UWSGI_CAP
cap_value_t *cap;
int cap_count;
#endif
// still working on it
char *profiler;
// mostly useless
char *mode;
// binary path the worker image
char *worker_exec;
// gateways
struct uwsgi_gateway gateways[MAX_GATEWAYS];
int gateways_cnt;
@@ -992,13 +1126,22 @@ struct uwsgi_server {
int ignore_script_name;
int manage_script_name;
int no_default_app;
int logdate;
int log_micros;
char *log_strftime;
int log_x_forwarded_for;
int honour_stdin;
// route all of the logs to the master process
int log_master;
int log_reopen;
int log_truncate;
off_t log_maxsize;
char *log_backupname;
int log_syslog;
int original_log_fd;
@@ -1007,15 +1150,21 @@ struct uwsgi_server {
union uwsgi_sockaddr *log_socket_addr;
socklen_t log_socket_size;
// static file serving
char *check_static;
size_t check_static_len;
int file_serve_mode;
int build_mime_dict;
char *mime_file;
struct uwsgi_static_map *static_maps;
struct uwsgi_dyn_dict *mimetypes;
char *logfile;
int logfile_chown;
// enable vhost mode
int vhost;
int vhost_host;
@@ -1023,6 +1172,7 @@ struct uwsgi_server {
char **async_buf;
char **async_post_buf;
// async commodity
struct wsgi_request **async_waiting_fd_table;
struct wsgi_request **async_proto_fd_table;
struct uwsgi_async_request *async_runqueue;
@@ -1039,19 +1189,27 @@ struct uwsgi_server {
int **async_ovector;
#endif
// store rlimit
struct rlimit rl;
size_t limit_post;
// set process priority
int prio;
int reload_on_as;
int reload_on_rss;
char *touch_reload;
time_t last_touch_reload_mtime;
// funny reload systems
int force_get_memusage;
rlim_t reload_on_as;
rlim_t reload_on_rss;
rlim_t evil_reload_on_as;
rlim_t evil_reload_on_rss;
struct uwsgi_string_list *touch_reload;
int propagate_touch;
// enable grunt mode
int grunt;
// store the binary path
char *binary_path;
int is_a_reload;
@@ -1067,7 +1225,9 @@ struct uwsgi_server {
#ifdef UWSGI_SPOOLER
char *spool_dir;
char *spooler_chdir;
int spooler_ordered;
uint64_t spooler_respawned;
#endif
#ifdef UWSGI_SNMP
@@ -1085,6 +1245,7 @@ struct uwsgi_server {
int buffer_size;
// post buffering
int post_buffering;
int post_buffering_harakiri;
int post_buffering_bufsize;
@@ -1092,6 +1253,7 @@ struct uwsgi_server {
int master_process;
int master_queue;
// mainly iseful for broodlord mode
int vassal_sos_backlog;
int no_defer_accept;
@@ -1116,10 +1278,12 @@ struct uwsgi_server {
int max_vars;
int vec_size;
// shared area
char *sharedarea;
uint64_t sharedareasize;
#ifdef UWSGI_THREADING
// avoid thundering herd in threaded modes
pthread_mutex_t six_feet_under_lock;
#endif
@@ -1127,12 +1291,16 @@ struct uwsgi_server {
/* the list of workers */
struct uwsgi_worker *workers;
/* the dedicated signal_pipe */
int **signal_pipe;
/* the list of mules */
struct uwsgi_string_list *mules_patches;
struct uwsgi_mule *mules;
pid_t mypid;
int mywid;
int muleid;
int mules_cnt;
rlim_t max_fd;
struct timeval start_tv;
@@ -1172,7 +1340,7 @@ struct uwsgi_server {
#endif
#ifdef UWSGI_INI
char *ini;
struct uwsgi_string_list *ini;
#endif
#ifdef UWSGI_SQLITE3
@@ -1203,6 +1371,7 @@ struct uwsgi_server {
char *cwd;
// conditional logging
int log_slow_requests;
int log_zero_headers;
int log_empty_body;
@@ -1304,6 +1473,10 @@ struct uwsgi_server {
int cache_server_fd;
pthread_mutex_t cache_server_lock;
// the stats server
char *stats;
int stats_fd;
uint64_t queue_size;
uint64_t queue_blocksize;
void *queue;
@@ -1314,9 +1487,11 @@ struct uwsgi_server {
pthread_mutex_t thunder_mutex;
int locks;
void *cache_lock;
void *queue_lock;
void *user_lock;
void **user_lock;
void *signal_table_lock;
void *fmon_table_lock;
void *timer_table_lock;
@@ -1333,6 +1508,7 @@ struct uwsgi_server {
char *startup_daemons[MAX_DAEMONS];
int startup_daemons_cnt;
// subscription client
char *subscriptions[MAX_SUBSCRIPTIONS];
int subscriptions_cnt;
@@ -1433,6 +1609,7 @@ struct uwsgi_shared {
#ifdef UWSGI_SPOOLER
pid_t spooler_pid;
int spooler_frequency;
time_t spooler_harakiri;
#endif
#ifdef UWSGI_SNMP
@@ -1454,6 +1631,8 @@ struct uwsgi_shared {
#ifdef UWSGI_SPOOLER
int spooler_signal_pipe[2];
#endif
int mule_signal_pipe[2];
struct uwsgi_signal_entry signal_table[256];
struct uwsgi_fmon files_monitored[64];
@@ -1524,8 +1703,7 @@ struct uwsgi_worker {
uint64_t vsz_size;
uint64_t rss_size;
double running_time;
double last_running_time;
uint64_t running_time;
int manage_next_request;
@@ -1536,6 +1714,43 @@ struct uwsgi_worker {
int apps_cnt;
struct uwsgi_app apps[MAX_APPS];
uint64_t tx;
int busy;
int cheaped;
int sig;
uint8_t signum;
// signals managed by this worker
uint64_t signals;
int signal_pipe[2];
uint64_t avg_response_time;
char name[0xff];
};
struct uwsgi_mule {
int id;
pid_t pid;
int signal_pipe[2];
int queue_pipe[2];
time_t last_spawn;
uint64_t respawn_count;
char *patch;
// signals managed by this mule
uint64_t signals;
int sig;
uint8_t signum;
time_t harakiri;
char name[0xff];
};
@@ -1588,6 +1803,8 @@ pid_t spooler_start(void);
#endif
void set_harakiri(int);
void set_mule_harakiri(int);
void set_spooler_harakiri(int);
void inc_harakiri(int);
#ifdef __BIG_ENDIAN__
@@ -1706,7 +1923,7 @@ char *uwsgi_concat4n(char *, int, char *, int, char *, int, char *, int);
int uwsgi_get_app_id(char *, int, int);
char *uwsgi_strncopy(char *, int);
void master_loop(char **, char **);
int master_loop(char **, char **);
int find_worker_id(pid_t);
@@ -1908,6 +2125,9 @@ struct uwsgi_dict {
void *data;
void *lock;
uint64_t count;
struct uwsgi_dict_item *items;
};
@@ -2113,6 +2333,7 @@ socklen_t socket_to_in_addr(char *, char *, struct sockaddr_in *);
socklen_t socket_to_un_addr(char *, struct sockaddr_un *);
int uwsgi_get_shared_socket_fd_by_num(int);
struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int);
int uwsgi_get_shared_socket_num(struct uwsgi_socket *);
@@ -2155,6 +2376,29 @@ char *uwsgi_str_contains(char *, int, char);
int uwsgi_simple_parse_vars(struct wsgi_request *, char *, char *);
void uwsgi_build_mime_dict(char *);
struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **, char *, int, char *, int);
void uwsgi_send_stats(int);
void uwsgi_apply_config_pass(char symbol, char*(*)(char *) );
void uwsgi_mule(int);
char *uwsgi_string_get_list(struct uwsgi_string_list **, int, size_t *);
void uwsgi_fixup_fds(int, int);
void uwsgi_set_processname(char *);
void http_url_decode(char *, uint16_t *, char *);
pid_t uwsgi_fork(char *);
#ifdef UWSGI_CAP
void uwsgi_build_cap(char *);
#endif
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);
#endif
+18 -2
View File
@@ -264,20 +264,36 @@ $(document).ready(function() {
<a name="workers"></a>
<h3>Workers</h3>
<div class="info">
<table width="400">
<table width="600">
<tr>
<th>#</th>
<th>pid</th>
<th>status</th>
<th>requests</th>
<th>exceptions</th>
<th>signals</th>
<th>running time</th>
<th>avg response time</th>
{% if 'memory-report' in uwsgi.opt %}
<th>rss</th>
<th>vsz</th>
{% endif %}
<th># respawn</th>
</tr>
{% for w in uwsgi.workers() %}
<tr class="{{ loop.cycle('odd', 'even') }}">
<td>{{w.id}}</td>
<td>{{w.pid}}</td>
<td>{{w.status}}</td>
<td>{{w.requests}}</td>
<td>{{w.exceptions}}</td>
<td>{{w.signals}}</td>
<td>{{w.running_time/1000}}</td>
<td>{{w.avg_rt/1000}}</td>
{% if 'memory-report' in uwsgi.opt %}
<td>{{(w.rss/1000/1000)|round(2,'floor')}}MB</td>
<td>{{(w.vsz/1000/1000)|round(2,'floor')}}MB</td>
{% endif %}
<td>{{w.respawn_count}}</td>
</tr>
{% endfor %}
@@ -294,7 +310,7 @@ $(document).ready(function() {
<div class="info">
{% for w in uwsgi.workers() %}
worker {{w.id}}
<table width="400">
<table width="600">
<tr>
<th>#</th>
<th>modifier1</th>
+111 -22
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '0.9.9-dev'
uwsgi_version = '1.0-dev'
import os
import re
@@ -25,13 +25,15 @@ GCC = os.environ.get('CC', sysconfig.get_config_var('CC'))
if not GCC:
GCC = 'gcc'
CPP = os.environ.get('CPP', 'cpp')
binary_list = []
def binarize(name):
return name.replace('/', '_').replace('.','_').replace('-','_')
def spcall(cmd):
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=open('/dev/null','w'))
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=open('uwsgibuild.log','w'))
if p.wait() == 0:
if sys.version_info[0] > 2:
@@ -57,10 +59,22 @@ def spcall2(cmd):
else:
return None
def spcall3(cmd):
p = subprocess.Popen(cmd, shell=True, stdin=open('/dev/null'), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
if p.wait() == 0:
if sys.version_info[0] > 2:
return p.stderr.read().rstrip().decode()
return p.stderr.read().rstrip()
else:
return None
def add_o(x):
if x == 'uwsgi':
x = 'main'
elif x.endswith('.a'):
return x
x = x + '.o'
return x
@@ -100,7 +114,7 @@ def build_uwsgi(uc):
epc = "-DUWSGI_DECLARE_EMBEDDED_PLUGINS=\""
eplc = "-DUWSGI_LOAD_EMBEDDED_PLUGINS=\""
for p in ep:
p = p.rstrip().lstrip()
p = p.strip()
if p == 'ugreen':
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
continue
@@ -117,7 +131,8 @@ def build_uwsgi(uc):
objfile = file
if objfile == 'uwsgi':
objfile = 'main'
compile(' '.join(cflags), objfile + '.o', file + '.c')
if not objfile.endswith('.a'):
compile(' '.join(cflags), objfile + '.o', file + '.c')
if uc.get('embedded_plugins'):
ep = uc.get('embedded_plugins').split(',')
@@ -125,7 +140,7 @@ def build_uwsgi(uc):
if len(ep) > 0:
print("*** uWSGI compiling embedded plugins ***")
for p in ep:
p = p.rstrip().lstrip()
p = p.strip()
if p == 'ugreen':
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
@@ -140,10 +155,18 @@ def build_uwsgi(uc):
p_cflags = cflags[:]
p_cflags += up.CFLAGS
try:
p_cflags.remove('-Wdeclaration-after-statement')
except:
pass
for cfile in up.GCC_LIST:
compile(' '.join(p_cflags),
path + '/' + cfile + '.o', path + '/' + cfile + '.c')
gcc_list.append('%s/%s' % (path, cfile))
if not cfile.endswith('.a'):
compile(' '.join(p_cflags),
path + '/' + cfile + '.o', path + '/' + cfile + '.c')
gcc_list.append('%s/%s' % (path, cfile))
else:
gcc_list.append(cfile)
libs += up.LIBS
ldflags += up.LDFLAGS
@@ -160,7 +183,7 @@ def build_uwsgi(uc):
print("*** uWSGI building plugins ***")
for p in plugins:
p = p.rstrip().lstrip()
p = p.strip()
print("*** building plugin: %s ***" % p)
build_plugin("plugins/%s" % p, uc, cflags, ldflags, libs)
@@ -195,25 +218,62 @@ class uConf(object):
print("using profile: %s" % filename)
if not os.path.exists(filename):
raise Exception("profile not found !!!")
if os.path.exists('uwsgibuild.lastprofile'):
ulp = open('uwsgibuild.lastprofile','r')
last_profile = ulp.read()
ulp.close()
if last_profile != filename:
os.environ['UWSGI_FORCE_REBUILD'] = '1'
ulp = open('uwsgibuild.lastprofile','w')
ulp.write(filename)
ulp.close()
self.config.read(filename)
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify',
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'master_utils', 'emperor', 'notify', 'mule',
'plugins', 'lock', 'cache', 'queue', 'event', 'signal', 'rpc', 'gateway', 'loop', 'lib/rbtree', 'lib/amqp', 'rb_timers', 'uwsgi']
# add protocols
self.gcc_list.append('proto/base')
self.gcc_list.append('proto/uwsgi')
self.gcc_list.append('proto/http')
self.gcc_list.append('proto/fastcgi')
self.include_path = []
if uwsgi_os == 'Linux':
self.gcc_list.append('lib/linux_ns')
self.gcc_list.append('lib/netlink')
self.cflags = ['-O2', '-Wall', '-Werror', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] + os.environ.get("CFLAGS", "").split()
try:
gcc_version = str(spcall("%s -dumpversion" % GCC))
except:
print("*** you need a c compiler to build uWSGI ***")
sys.exit(1)
gcc_major = int(gcc_version.split('.')[0])
gcc_minor = int(gcc_version.split('.')[1])
try:
add_it = False
cpp_include_list = str(spcall3("%s -v" % CPP)).split("\n")
for line in cpp_include_list:
if line.startswith('#include <...> search starts here:'):
add_it = True
elif line.startswith('End of search list.'):
add_it = False
elif add_it:
self.include_path.append(line.strip().split()[0])
if not self.include_path:
raise
except:
self.include_path = ['/usr/include', '/usr/local/include']
print("detected include path: %s" % self.include_path)
try:
gcc_major = int(gcc_version.split('.')[0])
gcc_minor = int(gcc_version.split('.')[1])
except:
raise Exception("you need a C compiler to build uWSGI")
if (sys.version_info[0] == 2) or (gcc_major < 4) or (gcc_major == 4 and gcc_minor < 3):
self.cflags = self.cflags + ['-fno-strict-aliasing']
# add -fno-strict-aliasing only on python2 and gcc < 4.3
@@ -266,6 +326,12 @@ class uConf(object):
print("%s needs %s support." % (what, d))
sys.exit(1)
def has_include(self, what):
for include in self.include_path:
if os.path.exists("%s/%s" %(include, what)):
return True
return False
def get_gcll(self):
global uwsgi_version
@@ -273,7 +339,7 @@ class uConf(object):
self.cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
kvm_list = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly']
if os.path.exists('/usr/include/ifaddrs.h') or os.path.exists('/usr/local/include/ifaddrs.h'):
if self.has_include('ifaddrs.h'):
self.cflags.append('-DUWSGI_HAS_IFADDRS')
if uwsgi_os == 'SunOS':
@@ -369,7 +435,7 @@ class uConf(object):
if timer_mode == 'timerfd':
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_TIMERFD')
if not os.path.exists('/usr/include/sys/timerfd.h') and not os.path.exists('/usr/local/include/sys/timerfd.h'):
if not self.has_include('sys/timerfd.h'):
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_TIMERFD_NOINC')
elif timer_mode == 'kqueue':
self.cflags.append('-DUWSGI_EVENT_TIMER_USE_KQUEUE')
@@ -412,6 +478,9 @@ class uConf(object):
self.ldflags.append('-shared')
self.ldflags.append('-fPIC')
self.cflags.append('-DUWSGI_AS_SHARED_LIBRARY')
if uwsgi_os == 'Darwin':
self.ldflags.append('-dynamiclib')
self.ldflags.append('-undefined dynamic_lookup')
if self.get('embedded'):
self.cflags.append('-DUWSGI_EMBEDDED')
@@ -420,7 +489,7 @@ class uConf(object):
self.cflags.append("-DUWSGI_UDP")
# re-enable after pcre fix
if self.get('pcreOFF'):
if self.get('pcre'):
if self.get('pcre') == 'auto':
pcreconf = spcall('pcre-config --libs')
if pcreconf:
@@ -442,10 +511,14 @@ class uConf(object):
self.gcc_list.append('regexp')
self.cflags.append("-DUWSGI_PCRE")
if self.has_include('sys/capability.h'):
self.cflags.append("-DUWSGI_CAP")
self.libs.append('-lcap')
has_json = False
has_uuid = False
if os.path.exists('/usr/include/uuid/uuid.h') or os.path.exists('/usr/local/include/uuid/uuid.h'):
if self.has_include('uuid/uuid.h'):
has_uuid = True
self.cflags.append("-DUWSGI_UUID")
if os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
@@ -550,7 +623,7 @@ class uConf(object):
self.cflags.append("-DUWSGI_LIBYAML")
self.libs.append('-lyaml')
if self.get('yaml_implementation') == 'auto':
if os.path.exists('/usr/include/yaml.h') or os.path.exists('/usr/local/include/yaml.h'):
if self.has_include('yaml.h'):
self.cflags.append("-DUWSGI_LIBYAML")
self.libs.append('-lyaml')
@@ -563,7 +636,7 @@ class uConf(object):
self.gcc_list.append('json')
self.libs.append(spcall("pkg-config --libs jansson"))
has_json = True
elif os.path.exists('/usr/include/jansson.h') or os.path.exists('/usr/local/include/jansson.h'):
elif self.has_include('jansson.h'):
self.cflags.append("-DUWSGI_JSON")
self.gcc_list.append('json')
self.libs.append('-ljansson')
@@ -576,7 +649,7 @@ class uConf(object):
if self.get('ldap'):
if self.get('ldap') == 'auto':
if os.path.exists('/usr/include/ldap.h'):
if self.has_include('ldap.h'):
self.cflags.append("-DUWSGI_LDAP")
self.gcc_list.append('ldap')
self.libs.append('-lldap')
@@ -587,7 +660,7 @@ class uConf(object):
if has_uuid and self.get('zeromq'):
if self.get('zeromq') == 'auto':
if os.path.exists('/usr/include/zmq.h') or os.path.exists('/usr/local/include/zmq.h'):
if self.has_include('zmq.h'):
self.cflags.append("-DUWSGI_ZEROMQ")
self.gcc_list.append('proto/zeromq')
self.libs.append('-lzmq')
@@ -635,7 +708,7 @@ class uConf(object):
if self.get('sqlite3'):
if self.get('sqlite3') == 'auto':
if os.path.exists('/usr/include/sqlite3.h') or os.path.exists('/usr/local/include/sqlite3.h'):
if self.has_include('sqlite3.h'):
self.cflags.append("-DUWSGI_SQLITE3")
self.libs.append('-lsqlite3')
self.gcc_list.append('sqlite3')
@@ -683,6 +756,12 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
else:
p_cflags.append("-D%s_plugin=%s_plugin" % (up.NAME, name))
try:
for opt in uc.config.options(name):
p_cflags.append('-DUWSGI_PLUGIN_%s_%s="%s"' % (name.upper(), opt.upper(), uc.config.get(name, opt, '1')))
except:
pass
plugin_dest = uc.get('plugin_dir') + '/' + name + '_plugin'
shared_flag = '-shared'
@@ -693,7 +772,9 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
shared_flag = '-dynamiclib -undefined dynamic_lookup'
for cfile in up.GCC_LIST:
if not cfile.endswith('.c') and not cfile.endswith('.cc'):
if cfile.endswith('.a'):
gcc_list.append(cfile)
elif not cfile.endswith('.c') and not cfile.endswith('.cc'):
gcc_list.append(path + '/' + cfile + '.c')
else:
gcc_list.append(path + '/' + cfile)
@@ -703,6 +784,14 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
except:
pass
try:
p_cflags.remove('-Wdeclaration-after-statement')
except:
pass
#for ofile in up.OBJ_LIST:
# gcc_list.insert(0,ofile)
gccline = "%s -fPIC %s -o %s.so %s %s %s %s" % (GCC, shared_flag, plugin_dest, ' '.join(p_cflags), ' '.join(p_ldflags), ' '.join(gcc_list), ' '.join(p_libs) )
print(gccline)
+3
View File
@@ -153,6 +153,9 @@ class lock(object):
self.f = f
def __call__(self, *args, **kwargs):
# ensure the spooler will not call it
if uwsgi.i_am_the_spooler():
return
uwsgi.lock()
try:
return self.f(*args, **kwargs)
+11
View File
@@ -0,0 +1,11 @@
[uwsgi]
socket = :$(PORT)
socket = /tmp/uwsgi_welcome.socket
vacuum = true
appname = welcome
module = %(appname)
numproc = 4
master = %(vacuum)
processes = %(numproc)
mount = /werkzeug=tests/werkzeug.py
manage-script-name = true
+63 -1
View File
@@ -1,5 +1,23 @@
import uwsgi
import os
import gc
import sys
from uwsgidecorators import *
gc.set_debug(gc.DEBUG_SAVEALL)
print os.environ
print sys.modules
print sys.argv
try:
if sys.argv[1] == 'debug':
DEBUG = True
else:
raise
except:
DEBUG = False
def xsendfile(e, sr):
sr('200 OK', [('Content-Type', 'image/png'), ('X-Sendfile', os.path.abspath('logo_uWSGI.png'))])
@@ -25,13 +43,48 @@ routes['/logo'] = serve_logo
routes['/config'] = serve_config
routes['/options'] = serve_options
@postfork
def setprocname():
if uwsgi.worker_id() > 0:
uwsgi.setprocname("i am the worker %d" % uwsgi.worker_id())
def application(env, start_response):
uwsgi.mule_msg(env['REQUEST_URI'], 1)
req = uwsgi.workers()[uwsgi.worker_id()-1]['requests']
uwsgi.setprocname("worker %d managed %d requests" % (uwsgi.worker_id(), req))
gc.collect(2)
if DEBUG:
print env['wsgi.input'].fileno()
if routes.has_key(env['PATH_INFO']):
return routes[env['PATH_INFO']](env, start_response)
start_response('200 OK', [('Content-Type', 'text/html')])
if DEBUG:
print env['wsgi.input'].fileno()
gc.collect(2)
if DEBUG:
print len(gc.get_objects())
workers = ''
for w in uwsgi.workers():
apps = '<table border="1"><tr><th>id</th><th>mountpoint</th><th>requests</th></tr>'
for app in w['apps']:
apps += '<tr><td>%d</td><td>%s</td><td>%d</td></tr>' % (app['id'], app['mountpoint'], app['requests'])
apps += '</table>'
workers += """
<tr>
<td>%d</td><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td><td>%s</td>
</tr>
""" % (w['id'], w['pid'], w['status'], w['running_time']/1000, w['avg_rt']/1000, w['tx'], apps)
return """
<img src="/logo"/> version %s<br/>
<hr size="1"/>
@@ -44,7 +97,16 @@ Configuration<br/>
Dynamic options<br/>
<iframe src="/options"></iframe><br/>
""" % (uwsgi.version)
<br/>
Workers and applications<br/>
<table border="1">
<tr>
<th>wid</th><th>pid</th><th>status</th><th>running time</th><th>average</th><th>tx</th><th>apps</th>
</tr>
%s
</table>
""" % (uwsgi.version, workers)
+1 -1
View File
@@ -26,7 +26,7 @@ void uwsgi_xml_config(char *filename, struct wsgi_request *wsgi_req, int app_tag
char *xml_content;
int xml_size = 0;
if (!uwsgi_startswith(filename, "http://", 7) || !uwsgi_startswith(filename, "data://", 7) || !uwsgi_startswith(filename, "sym://", 6)) {
if (uwsgi_check_scheme(filename)) {
colon = uwsgi_get_last_char(filename, '/');
colon = uwsgi_get_last_char(colon, ':');
}
+1 -1
View File
@@ -107,7 +107,7 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
char *section_asked = "uwsgi";
char *colon;
if (!uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6)) {
if (uwsgi_check_scheme(file)) {
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}