From be16bb5f9477d70d25fa29430cf94a0fd233691b Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Mon, 26 Aug 2019 16:42:54 +0800 Subject: [PATCH 01/41] build for win --- .gitignore | 3 + gulpfile.js | 24 + package.json | 16 +- worker/deps/libsrtp/libsrtp.gyp | 1 + worker/include/Utils.hpp | 7 + worker/include/common.hpp | 20 +- worker/include/opt/getopt.h | 101 ++++ worker/mediasoup-worker.gyp | 28 +- worker/opt/getopt.cpp | 862 +++++++++++++++++++++++++++ worker/scripts/configure.py | 5 + worker/src/Logger.cpp | 2 + worker/src/RTC/DtlsTransport.cpp | 10 +- worker/src/Settings.cpp | 4 + worker/src/Utils/File.cpp | 6 + worker/src/handles/TcpConnection.cpp | 2 +- worker/src/main.cpp | 8 +- 16 files changed, 1084 insertions(+), 15 deletions(-) create mode 100644 worker/include/opt/getopt.h create mode 100644 worker/opt/getopt.cpp diff --git a/.gitignore b/.gitignore index 6617bc2b77..8213ba1c7f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ # Mac Stuff. .DS_Store + +# Win Stuff +configure.pyc diff --git a/gulpfile.js b/gulpfile.js index bad255eab7..a3ab592e15 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,5 +1,7 @@ const gulp = require('gulp'); +const shell = require('gulp-shell'); const clangFormat = require('gulp-clang-format'); +const os = require('os'); const workerFiles = [ @@ -37,3 +39,25 @@ gulp.task('format:worker', () => .pipe(clangFormat.format('file')) .pipe(gulp.dest('.')); }); + +gulp.task('win:build', shell.task( + [ + 'echo build for windows', + 'cd worker && python ./scripts/configure.py --format=msvs', + `MSBuild ./worker/out/mediasoup-worker.sln /p:Configuration=${process.env.MEDIASOUP_BUILDTYPE === 'Debug' ?'Debug' : 'Release'} -t:mediasoup-worker ` + ], + { + verbose : true, + } +)); + +gulp.task('make:build', shell.task( + [ + 'make -C worker' + ], + { + verbose : true + } +)); + +gulp.task('build', gulp.series(os.platform() === 'win32'? 'win:build' : 'make:build')); diff --git a/package.json b/package.json index 0d33b9cb72..f6f6416163 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,6 @@ "sfu", "nodejs" ], - "os": [ - "!win32" - ], "engines": { "node": ">=8.6.0" }, @@ -34,7 +31,7 @@ "test:node": "make -C worker && jest", "test:worker": "make test -C worker", "coverage:node": "make -C worker && jest --coverage && open-cli coverage/lcov-report/index.html", - "postinstall": "make -C worker" + "postinstall": "gulp build" }, "jest": { "verbose": true, @@ -46,13 +43,18 @@ "h264-profile-level-id": "^1.0.0", "netstring": "^0.3.0", "random-number": "^0.0.9", - "uuid": "^3.3.2" + "uuid": "^3.3.2", + "gulp": "^4.0.2", + "gulp-clang-format": "^1.0.27", + "gulp-eslint": "^6.0.0", + "gulp-rename": "^1.4.0", + "gulp-replace": "^1.0.0", + "gulp-shell": "^0.6.5", + "gulp-touch-cmd": "0.0.1" }, "devDependencies": { "eslint": "^6.1.0", "eslint-plugin-jest": "^22.13.6", - "gulp": "^4.0.2", - "gulp-clang-format": "^1.0.27", "jest": "^24.8.0", "jest-tobetype": "^1.2.3", "open-cli": "^5.0.0", diff --git a/worker/deps/libsrtp/libsrtp.gyp b/worker/deps/libsrtp/libsrtp.gyp index 8919320d79..9b0a9be076 100644 --- a/worker/deps/libsrtp/libsrtp.gyp +++ b/worker/deps/libsrtp/libsrtp.gyp @@ -53,6 +53,7 @@ # All Windows architectures are this way. 'SIZEOF_UNSIGNED_LONG=4', 'SIZEOF_UNSIGNED_LONG_LONG=8', + 'HAVE_WINSOCK2_H', ], }], ['target_arch=="x64" or target_arch=="ia32"', { diff --git a/worker/include/Utils.hpp b/worker/include/Utils.hpp index fc832b415b..07ace3692c 100644 --- a/worker/include/Utils.hpp +++ b/worker/include/Utils.hpp @@ -6,6 +6,13 @@ #include #include // std::memcmp(), std::memcpy() #include +#ifdef _MSC_VER +#include +// https://stackoverflow.com/a/24550632/2085408 +#include +#define __builtin_popcount __popcnt +#endif // _WIN32 + namespace Utils { diff --git a/worker/include/common.hpp b/worker/include/common.hpp index d106f9962c..4f631b1a39 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -2,12 +2,28 @@ #define MS_COMMON_HPP #include // std::transform(), std::find(), std::min(), std::max() +#ifdef _MSC_VER +#include +#undef max // https://stackoverflow.com/a/27443191/2085408 +#undef min + +// avoid uv/win.h: error C2628 'intptr_t' followed by 'int' is illegal +#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) +#include +typedef SSIZE_T ssize_t; +# define SSIZE_MAX INTPTR_MAX +# define _SSIZE_T_ +# define _SSIZE_T_DEFINED +#endif + +#else #include // htonl(), htons(), ntohl(), ntohs() +#include // sockaddr_in, sockaddr_in6 +#include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 +#endif // _WINDOWS #include // PRIu64, etc #include // size_t #include // uint8_t, etc #include // std::addressof() -#include // sockaddr_in, sockaddr_in6 -#include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 #endif diff --git a/worker/include/opt/getopt.h b/worker/include/opt/getopt.h new file mode 100644 index 0000000000..5ff8bee32c --- /dev/null +++ b/worker/include/opt/getopt.h @@ -0,0 +1,101 @@ +#ifndef _GETOPT_H +#define _GETOPT_H + +#ifdef __cplusplus + +extern "C" { +#endif + + /* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here.*/ + + extern char *optarg; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far.*/ + + extern int optind; + + /* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options.*/ + + extern int opterr; + + /* Set to an option character which was unrecognized.*/ + + extern int optopt; + + /* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument(or 0) if the option does not take an argument, + required_argument(or 1) if the option requires an argument, + optional_argument(or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one).For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field.*/ + + struct option + { +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int.*/ + int has_arg; + int *flag; + int val; + }; + + /* Names for the values of the `has_arg' field of `struct option'.*/ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + + extern int getopt_long(int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); + extern int getopt_long_only(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + + /* Internal only.Users should not call this directly.*/ + extern int _getopt_internal(int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); + extern int + getopt(int argc, + char *const *argv, + const char *optstring); + + #ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/worker/mediasoup-worker.gyp b/worker/mediasoup-worker.gyp index e5741befb9..f6048d0940 100644 --- a/worker/mediasoup-worker.gyp +++ b/worker/mediasoup-worker.gyp @@ -271,6 +271,13 @@ 'ldflags': [ '-Wl,--export-dynamic' ] }], + [ 'OS == "win"', { + 'sources': [ + 'include/opt/getopt.h', + 'opt/getopt.cpp' + ] + }], + [ 'OS != "win"', { 'cflags': [ '-std=c++11', '-Wall', '-Wextra', '-Wno-unused-parameter', '-Wno-implicit-fallthrough' ] }], @@ -298,7 +305,13 @@ [ # C++ source files. 'src/main.cpp' - ] + ], + # handle multi files with same name + # https://stackoverflow.com/a/22936230/2085408 + # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile + 'msvs_settings': { + 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, + } }, { 'target_name': 'mediasoup-worker-test', @@ -356,6 +369,12 @@ 'OTHER_LDFLAGS': [ '--coverage' ] + }, + # handle multi files with same name + # https://stackoverflow.com/a/22936230/2085408 + # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile + 'msvs_settings': { + 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, } }, { @@ -419,6 +438,13 @@ [ 'fuzzer/include' ], + # handle multi files with same name + # https://stackoverflow.com/a/22936230/2085408 + # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile + 'msvs_settings': { + 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, + }, + 'conditions': [ [ 'OS == "linux"', { diff --git a/worker/opt/getopt.cpp b/worker/opt/getopt.cpp new file mode 100644 index 0000000000..fbd2182fc0 --- /dev/null +++ b/worker/opt/getopt.cpp @@ -0,0 +1,862 @@ +#include +#include +#include + +#define getpid() GetCurrentProcessId() + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. +When compiling libc, the _ macro is predefined. */ +#ifdef NEVER_HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' +but it behaves differently for the user, since it allows the user +to intersperse the options with the other arguments. + +As `getopt' works, it permutes the elements of ARGV so that, +when it is done, all the options precede everything else. Thus +all application programs are extended to handle flexible argument order. + +Setting the environment variable POSIXLY_CORRECT disables permutation. +Then the behavior is completely standard. + +GNU application programs can use a third alternative mode in which +they can distinguish the relative order of options and other arguments. */ + +#include "opt/getopt.h" + +/* For communication from `getopt' to the caller. +When `getopt' finds an option that takes an argument, +the argument value is returned here. +Also, when `ordering' is RETURN_IN_ORDER, +each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. +This is used for communication to and from the caller +and for communication between successive calls to `getopt'. + +On entry to `getopt', zero means this is the first call; initialize. + +When `getopt' returns -1, this is the index of the first of the +non-option elements that the caller should itself scan. + +Otherwise, `optind' communicates from one call to the next +how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which +causes problems with re-calling getopt as programs generally don't +know that. */ + +int __getopt_initialized = 0; + +/* The next char to be scanned in the option-element +in which the last option character we returned was found. +This allows us to pick up the scan where we left off. + +If this is zero, or a null string, it means resume the scan +by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message +for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. +This must be initialized on some systems to avoid linking in the +system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + +If the caller did not specify anything, +the default is REQUIRE_ORDER if the environment variable +POSIXLY_CORRECT is defined, PERMUTE otherwise. + +REQUIRE_ORDER means don't recognize them as options; +stop option processing when the first non-option is seen. +This is what Unix does. +This mode of operation is selected by either setting the environment +variable POSIXLY_CORRECT, or using `+' as the first character +of the list of option characters. + +PERMUTE is the default. We permute the contents of ARGV as we scan, +so that eventually all the non-options are at the end. This allows options +to be given in any order, even with programs that were not written to +expect this. + +RETURN_IN_ORDER is an option available to programs that were written +to expect options and other ARGV-elements in any order and that care about +the ordering of the two. We describe each non-option ARGV-element +as if it were the argument of an option with character code 1. +Using `-' as the first character of the list of option characters +selects this mode of operation. + +The special argument `--' forces an end of option-scanning regardless +of the value of `ordering'. In the case of RETURN_IN_ORDER, only +`--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +/* Avoid depending on library functions or files +whose names are inconsistent. */ + +char *getenv(); + +static char * +my_index(const char *str, int chr) +{ + while (*str) + { + if (*str == chr) + return (char *)str; + str++; + } + return 0; +} + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have +been skipped. `first_nonopt' is the index in ARGV of the first of them; +`last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + + +# define SWAP_FLAGS(ch1, ch2) + +/* Exchange two adjacent subsequences of ARGV. +One subsequence is elements [first_nonopt,last_nonopt) +which contains all the non-options that have been skipped so far. +The other is elements [last_nonopt,optind), which contains all +the options processed since those non-options were skipped. + +`first_nonopt' and `last_nonopt' are relocated so that they describe +the new indices of the non-options in ARGV after they are moved. */ + + + +static void +exchange(char **argv) + +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS(bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize(int argc, + char *const *argv, + const char *optstring) +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + // posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + //else if (posixly_correct != NULL) + // ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters +given in OPTSTRING. + +If an element of ARGV starts with '-', and is not exactly "-" or "--", +then it is an option element. The characters of this element +(aside from the initial '-') are option characters. If `getopt' +is called repeatedly, it returns successively each of the option characters +from each of the option elements. + +If `getopt' finds another option character, it returns that character, +updating `optind' and `nextchar' so that the next call to `getopt' can +resume the scan with the following option character or ARGV-element. + +If there are no more option characters, `getopt' returns -1. +Then `optind' is the index in ARGV of the first ARGV-element +that is not an option. (The ARGV-elements have been permuted +so that those that are not options now come last.) + +OPTSTRING is a string containing the legitimate option characters. +If an option character is seen that is not listed in OPTSTRING, +return '?' after printing an error message. If you set `opterr' to +zero, the error message is suppressed but we still return '?'. + +If a char in OPTSTRING is followed by a colon, that means it wants an arg, +so the following text in the same ARGV-element, or the text of the following +ARGV-element, is returned in `optarg'. Two colons mean an option that +wants an optional arg; if there is text in the current ARGV-element, +it is returned in `optarg', otherwise `optarg' is set to zero. + +If OPTSTRING starts with `-' or `+', it requests different methods of +handling the non-option ARGV-elements. +See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + +Long-named options begin with `--' instead of `-'. +Their names may be abbreviated as long as the abbreviation is unique +or is an exact match for some defined option. If they have an +argument, it follows the option name in the same ARGV-element, separated +from the option name by a `=', or else the in next ARGV-element. +When `getopt' finds a long-named option, it returns 0 if that option's +`flag' field is nonzero, the value of the option's `val' field +if the `flag' field is zero. + +The elements of ARGV aren't really const, because we permute them. +But we pretend they're const in the prototype to be compatible +with other systems. + +LONGOPTS is a vector of `struct option' terminated by an +element containing a name which is zero. + +LONGIND returns the index in LONGOPT of the long-named option found. +It is only valid when a long-named option has been found by the most +recent call. + +If LONG_ONLY is nonzero, '-' as well as '--' can introduce +long-named options. */ + +int +_getopt_internal(int argc, + char *const *argv, + const char *optstring, + const struct option *longopts, + int *longind, + int long_only) +{ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize(argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange((char **)argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp(argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange((char **)argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only + && (argv[optind][2] + || !my_index(optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int)(nameend - nextchar) + == (unsigned int)strlen(p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf(stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen(nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf(stderr, + _ + ("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf(stderr, + _ + ("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + + nextchar += strlen(nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf(stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen(nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen(nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index(optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf(stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf(stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index(optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c); + else + fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; + nameend++) + /* Do nothing. */; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int)(nameend - nextchar) == strlen(p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen(nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf(stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); + + nextchar += strlen(nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf(stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen(nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen(nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt(int argc, + char *const *argv, + const char *optstring) +{ + return _getopt_internal(argc, argv, optstring, + (const struct option *) 0, (int *)0, 0); +} + + +int +getopt_long(int argc, char *const * argv, const char * options, + const struct option * long_options, int *opt_index) +{ + return _getopt_internal(argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. +If an option that starts with '-' (not '--') doesn't match a long option, +but does match a short option, it is parsed as a short option +instead. */ + +int +getopt_long_only(int argc, char *const * argv, const char * options, + const struct option * long_options, int *opt_index) +{ + return _getopt_internal(argc, argv, options, long_options, opt_index, 1); +} + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing +the above definition of `getopt'. */ + +int +main(int argc, + char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt(argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf("option %c\n", c); + break; + + case 'a': + printf("option a\n"); + break; + + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + + return 0; +} + +#endif /* TEST */ diff --git a/worker/scripts/configure.py b/worker/scripts/configure.py index 01dfcca235..de878667b6 100755 --- a/worker/scripts/configure.py +++ b/worker/scripts/configure.py @@ -85,6 +85,11 @@ def run_gyp(args): args.append('-Dclang=%d' % int(is_clang)) if is_clang == False and major == 4 and minor <= 8: raise RuntimeError('gcc <= 4.8 not supported, please upgrade your gcc') + else: + if 'ninja' not in args: + args.extend(['-Goutput_dir=' + output_dir]) + args.extend(['--generator-output', output_dir]) + if not any(a.startswith('-Dhost_arch=') for a in args): args.append('-Dhost_arch=%s' % host_arch()) diff --git a/worker/src/Logger.cpp b/worker/src/Logger.cpp index 0e98af26d4..ede7e28308 100644 --- a/worker/src/Logger.cpp +++ b/worker/src/Logger.cpp @@ -2,7 +2,9 @@ // #define MS_LOG_DEV #include "Logger.hpp" +#ifndef _MSC_VER #include // getpid() +#endif /* Class variables. */ diff --git a/worker/src/RTC/DtlsTransport.cpp b/worker/src/RTC/DtlsTransport.cpp index e50c7758ad..d9b339b606 100644 --- a/worker/src/RTC/DtlsTransport.cpp +++ b/worker/src/RTC/DtlsTransport.cpp @@ -1276,13 +1276,13 @@ namespace RTC } } - uint8_t srtpMaterial[srtpMasterLength * 2]; + uint8_t* srtpMaterial = new uint8_t[srtpMasterLength * 2]; uint8_t* srtpLocalKey; uint8_t* srtpLocalSalt; uint8_t* srtpRemoteKey; uint8_t* srtpRemoteSalt; - uint8_t srtpLocalMasterKey[srtpMasterLength]; - uint8_t srtpRemoteMasterKey[srtpMasterLength]; + uint8_t* srtpLocalMasterKey = new uint8_t[srtpMasterLength]; + uint8_t* srtpRemoteMasterKey = new uint8_t[srtpMasterLength]; int ret; ret = SSL_export_keying_material( @@ -1335,6 +1335,10 @@ namespace RTC srtpRemoteMasterKey, srtpMasterLength, this->remoteCert); + + delete[]srtpMaterial; + delete[]srtpLocalMasterKey; + delete[]srtpRemoteMasterKey; } inline RTC::SrtpSession::Profile DtlsTransport::GetNegotiatedSrtpProfile() diff --git a/worker/src/Settings.cpp b/worker/src/Settings.cpp index 7a5674d3d3..d35d88a7e3 100644 --- a/worker/src/Settings.cpp +++ b/worker/src/Settings.cpp @@ -10,9 +10,13 @@ #include #include // std::ostream_iterator #include // std::ostringstream +#ifdef _MSC_VER +#include "opt/getopt.h" +#else extern "C" { #include } +#endif // _MSC_VER /* Class variables. */ diff --git a/worker/src/Utils/File.cpp b/worker/src/Utils/File.cpp index c41195702f..fb2199e23a 100644 --- a/worker/src/Utils/File.cpp +++ b/worker/src/Utils/File.cpp @@ -6,7 +6,13 @@ #include "Utils.hpp" #include #include // stat() +#ifdef _MSC_VER +#include +#define __S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask)) +#define S_ISREG(mode) __S_ISTYPE((mode), _S_IFREG) +#else #include // access(), R_OK +#endif // _WINDOWS namespace Utils { diff --git a/worker/src/handles/TcpConnection.cpp b/worker/src/handles/TcpConnection.cpp index a44370670a..e6a308d900 100644 --- a/worker/src/handles/TcpConnection.cpp +++ b/worker/src/handles/TcpConnection.cpp @@ -332,7 +332,7 @@ void TcpConnection::Write(const uint8_t* data1, size_t len1, const uint8_t* data void TcpConnection::ErrorReceiving() { - MS_ERROR(); + MS_ERROR(""); Close(); diff --git a/worker/src/main.cpp b/worker/src/main.cpp index 91947156ba..d452ca87ef 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -21,7 +21,11 @@ #include // std::cerr, std::endl #include #include -#include // usleep() +#ifdef _MSC_VER +#define usleep Sleep +#else +#include // getpid(), usleep() +#endif static constexpr int ChannelFd{ 3 }; @@ -137,6 +141,7 @@ int main(int argc, char* argv[]) void IgnoreSignals() { +#ifndef _MSC_VER MS_TRACE(); int err; @@ -170,4 +175,5 @@ void IgnoreSignals() if (err != 0) MS_THROW_ERROR("sigaction() failed for signal %s: %s", sigName.c_str(), std::strerror(errno)); } +#endif } From e9ee7c38e478560d01529f6bfc629f9bc88b7281 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Mon, 26 Aug 2019 23:49:40 +0800 Subject: [PATCH 02/41] code style --- .eslintrc.js | 3 ++- worker/include/Utils.hpp | 1 - worker/include/common.hpp | 12 ++++++------ worker/src/RTC/DtlsTransport.cpp | 8 ++++---- worker/src/Utils/File.cpp | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c2d0f1c8d8..fda983616f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -172,6 +172,7 @@ module.exports = 'spaced-comment': [ 2, 'always' ], 'strict': 2, 'valid-typeof': 2, - 'yoda': 2 + 'yoda': 2, + "linebreak-style": 0 } }; diff --git a/worker/include/Utils.hpp b/worker/include/Utils.hpp index 07ace3692c..8df9f7aa4e 100644 --- a/worker/include/Utils.hpp +++ b/worker/include/Utils.hpp @@ -13,7 +13,6 @@ #define __builtin_popcount __popcnt #endif // _WIN32 - namespace Utils { class IP diff --git a/worker/include/common.hpp b/worker/include/common.hpp index 4f631b1a39..408ae5b94e 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -1,9 +1,9 @@ #ifndef MS_COMMON_HPP #define MS_COMMON_HPP -#include // std::transform(), std::find(), std::min(), std::max() +#include // std::transform(), std::find(), std::min(), std::max() #ifdef _MSC_VER -#include +#include #undef max // https://stackoverflow.com/a/27443191/2085408 #undef min @@ -11,16 +11,16 @@ #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) #include typedef SSIZE_T ssize_t; -# define SSIZE_MAX INTPTR_MAX -# define _SSIZE_T_ -# define _SSIZE_T_DEFINED +#define SSIZE_MAX INTPTR_MAX +#define _SSIZE_T_ +#define _SSIZE_T_DEFINED #endif #else #include // htonl(), htons(), ntohl(), ntohs() #include // sockaddr_in, sockaddr_in6 #include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 -#endif // _WINDOWS +#endif // _WINDOWS #include // PRIu64, etc #include // size_t #include // uint8_t, etc diff --git a/worker/src/RTC/DtlsTransport.cpp b/worker/src/RTC/DtlsTransport.cpp index d9b339b606..4508076f84 100644 --- a/worker/src/RTC/DtlsTransport.cpp +++ b/worker/src/RTC/DtlsTransport.cpp @@ -1281,7 +1281,7 @@ namespace RTC uint8_t* srtpLocalSalt; uint8_t* srtpRemoteKey; uint8_t* srtpRemoteSalt; - uint8_t* srtpLocalMasterKey = new uint8_t[srtpMasterLength]; + uint8_t* srtpLocalMasterKey = new uint8_t[srtpMasterLength]; uint8_t* srtpRemoteMasterKey = new uint8_t[srtpMasterLength]; int ret; @@ -1336,9 +1336,9 @@ namespace RTC srtpMasterLength, this->remoteCert); - delete[]srtpMaterial; - delete[]srtpLocalMasterKey; - delete[]srtpRemoteMasterKey; + delete[] srtpMaterial; + delete[] srtpLocalMasterKey; + delete[] srtpRemoteMasterKey; } inline RTC::SrtpSession::Profile DtlsTransport::GetNegotiatedSrtpProfile() diff --git a/worker/src/Utils/File.cpp b/worker/src/Utils/File.cpp index fb2199e23a..2e0a30e955 100644 --- a/worker/src/Utils/File.cpp +++ b/worker/src/Utils/File.cpp @@ -7,12 +7,12 @@ #include #include // stat() #ifdef _MSC_VER -#include -#define __S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask)) -#define S_ISREG(mode) __S_ISTYPE((mode), _S_IFREG) +#include +#define __S_ISTYPE(mode, mask) (((mode)&_S_IFMT) == (mask)) +#define S_ISREG(mode) __S_ISTYPE((mode), _S_IFREG) #else -#include // access(), R_OK -#endif // _WINDOWS +#include // access(), R_OK +#endif // _WINDOWS namespace Utils { From 27c130755df4b2b2de1b745cb54f733908a0c3fe Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Mon, 26 Aug 2019 23:50:22 +0800 Subject: [PATCH 03/41] code style --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index a3ab592e15..e5b447f605 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -47,7 +47,7 @@ gulp.task('win:build', shell.task( `MSBuild ./worker/out/mediasoup-worker.sln /p:Configuration=${process.env.MEDIASOUP_BUILDTYPE === 'Debug' ?'Debug' : 'Release'} -t:mediasoup-worker ` ], { - verbose : true, + verbose : true } )); From f2b060ec6d770dca7f47afd1c793066a64f48bd8 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Mon, 26 Aug 2019 23:53:22 +0800 Subject: [PATCH 04/41] scripts --- gulpfile.js | 14 ++++++++++++++ package.json | 10 +++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index e5b447f605..c57663f9f2 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -61,3 +61,17 @@ gulp.task('make:build', shell.task( )); gulp.task('build', gulp.series(os.platform() === 'win32'? 'win:build' : 'make:build')); + +gulp.task('test:win:worker', shell.task( + [ + 'echo not support yet!!' + ] +)); + +gulp.task('test:make:worker', shell.task( + [ + 'make test -C worker' + ] +)); + +gulp.task('test:worker', gulp.series(os.platform() === 'win32'? 'test:win:worker' : 'test:make:worker')) diff --git a/package.json b/package.json index f6f6416163..f02e7575f0 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,12 @@ "scripts": { "lint": "npm run lint:node && npm run lint:worker", "lint:node": "eslint -c .eslintrc.js gulpfile.js lib test", - "lint:worker": "make lint -C worker", - "format:worker": "make format -C worker", + "lint:worker": "gulp lint:worker", + "format:worker": "gulp format:worker", "test": "npm run test:node && npm run test:worker", - "test:node": "make -C worker && jest", - "test:worker": "make test -C worker", - "coverage:node": "make -C worker && jest --coverage && open-cli coverage/lcov-report/index.html", + "test:node": "gulp build && jest", + "test:worker": "gulp test:worker", + "coverage:node": "gulp build && jest --coverage && open-cli coverage/lcov-report/index.html", "postinstall": "gulp build" }, "jest": { From 8de983ac3eb4376dfcf22a12938662ecfe40d922 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Thu, 29 Aug 2019 14:34:59 +0800 Subject: [PATCH 05/41] replace duplex pipe with two pipe --- .gitignore | 3 ++ gulpfile.js | 2 +- lib/Channel.js | 30 ++++++++++++------ lib/Worker.js | 8 +++-- test/test-Worker.js | 5 +++ worker/include/Channel/Request.hpp | 9 ++++-- worker/include/Channel/UnixStreamSocket.hpp | 14 ++++++++- worker/include/RTC/RTCP/FeedbackPsFir.hpp | 5 +++ worker/include/Worker.hpp | 4 +-- worker/include/common.hpp | 7 ++--- worker/include/handles/UnixStreamSocket.hpp | 8 ++++- worker/src/Channel/Request.cpp | 31 ++++++++++++++++--- worker/src/Channel/UnixStreamSocket.cpp | 6 ++-- worker/src/Worker.cpp | 9 ++++-- worker/src/handles/UnixStreamSocket.cpp | 34 ++++++++++++--------- worker/src/main.cpp | 12 +++++--- worker/test/include/helpers.hpp | 5 +++ 17 files changed, 137 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 8213ba1c7f..3f160e6b77 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ # Win Stuff configure.pyc + +# VS stuff +/worker/.vs/ \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index c57663f9f2..68e977864c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -64,7 +64,7 @@ gulp.task('build', gulp.series(os.platform() === 'win32'? 'win:build' : 'make:bu gulp.task('test:win:worker', shell.task( [ - 'echo not support yet!!' + 'echo not support yet!!! run test in visual studio!!!' ] )); diff --git a/lib/Channel.js b/lib/Channel.js index 7cd8e6c909..892f2a7d2b 100644 --- a/lib/Channel.js +++ b/lib/Channel.js @@ -12,7 +12,7 @@ class Channel extends EnhancedEventEmitter /** * @private */ - constructor({ socket, pid }) + constructor({ producerSocket, consumerSocket, pid }) { const logger = new Logger(`Channel[pid:${pid}]`); const workerLogger = new Logger(`worker[pid:${pid}]`); @@ -30,7 +30,8 @@ class Channel extends EnhancedEventEmitter // Unix Socket instance. // @type {net.Socket} - this._socket = socket; + this._producerSocket = producerSocket; + this._consumerSocket = consumerSocket; // Next request id. // @type {Number} @@ -45,7 +46,7 @@ class Channel extends EnhancedEventEmitter this._recvBuffer = null; // Read Channel responses/notifications from the worker. - this._socket.on('data', (buffer) => + this._consumerSocket.on('data', (buffer) => { if (!this._recvBuffer) { @@ -147,8 +148,11 @@ class Channel extends EnhancedEventEmitter } }); - this._socket.on('end', () => this._logger.debug('Channel ended by the worker process')); - this._socket.on('error', (error) => this._logger.error('Channel error: %s', String(error))); + this._consumerSocket.on('end', () => this._logger.debug('Consumer channel ended by the worker process')); + this._consumerSocket.on('error', (error) => this._logger.error('Consumer channel error: %s', String(error))); + + this._producerSocket.on('end', () => this._logger.debug('Producer channel ended by the worker process')); + this._producerSocket.on('error', (error) => this._logger.error('Producer channel error: %s', String(error))); } /** @@ -171,14 +175,20 @@ class Channel extends EnhancedEventEmitter // Remove event listeners but leave a fake 'error' hander to avoid // propagation. - this._socket.removeAllListeners('end'); - this._socket.removeAllListeners('error'); - this._socket.on('error', () => {}); + this._consumerSocket.removeAllListeners('end'); + this._consumerSocket.removeAllListeners('error'); + this._consumerSocket.on('error', () => {}); + + this._producerSocket.removeAllListeners('end'); + this._producerSocket.removeAllListeners('error'); + this._producerSocket.on('error', () => {}); // Destroy the socket after a while to allow pending incoming messages. setTimeout(() => { - try { this._socket.destroy(); } + try { this._producerSocket.destroy(); } + catch (error) {} + try { this._consumerSocket.destroy(); } catch (error) {} }, 200); } @@ -206,7 +216,7 @@ class Channel extends EnhancedEventEmitter throw new Error('Channel request too big'); // This may throw if closed or remote side ended. - this._socket.write(ns); + this._producerSocket.write(ns); return new Promise((pResolve, pReject) => { diff --git a/lib/Worker.js b/lib/Worker.js index 848135f291..55c8f5e66f 100644 --- a/lib/Worker.js +++ b/lib/Worker.js @@ -90,9 +90,10 @@ class Worker extends EnhancedEventEmitter * fd 0 (stdin) : Just ignore it. * fd 1 (stdout) : Pipe it for 3rd libraries that log their own stuff. * fd 2 (stderr) : Same as stdout. - * fd 3 (channel) : Channel fd. + * fd 3 (channel) : Producer Channel fd. + * fd 4 (channel) : Consumer Channel fd. */ - stdio : [ 'ignore', 'pipe', 'pipe', 'pipe' ] + stdio : [ 'ignore', 'pipe', 'pipe', 'pipe', 'pipe' ] }); this._workerLogger = new Logger(`worker[pid:${this._child.pid}]`); @@ -105,7 +106,8 @@ class Worker extends EnhancedEventEmitter // @type {Channel} this._channel = new Channel( { - socket : this._child.stdio[3], + producerSocket : this._child.stdio[3], + consumerSocket : this._child.stdio[4], pid : this._pid }); diff --git a/test/test-Worker.js b/test/test-Worker.js index 90553e805f..75fbf6ff7f 100644 --- a/test/test-Worker.js +++ b/test/test-Worker.js @@ -3,6 +3,7 @@ const { toBeType } = require('jest-tobetype'); const mediasoup = require('../'); const { createWorker, observer } = mediasoup; const { InvalidStateError } = require('../lib/errors'); +const os = require('os'); expect.extend({ toBeType }); @@ -194,6 +195,10 @@ test('Worker emits "died" if worker process died unexpectedly', async () => test('worker process ignores PIPE, HUP, ALRM, USR1 and USR2 signals', async () => { + if (os.platform() === 'win32') { + return; + } + worker = await createWorker({ logLevel: 'warn' }); await new Promise((resolve, reject) => diff --git a/worker/include/Channel/Request.hpp b/worker/include/Channel/Request.hpp index ed02f96cbc..4fea1c39e8 100644 --- a/worker/include/Channel/Request.hpp +++ b/worker/include/Channel/Request.hpp @@ -67,7 +67,7 @@ namespace Channel static std::unordered_map string2MethodId; public: - Request(Channel::UnixStreamSocket* channel, json& jsonRequest); + Request(json& jsonRequest); virtual ~Request(); void Accept(); @@ -76,8 +76,6 @@ namespace Channel void TypeError(const char* reason = nullptr); public: - // Passed by argument. - Channel::UnixStreamSocket* channel{ nullptr }; uint32_t id{ 0u }; std::string method; MethodId methodId; @@ -85,6 +83,11 @@ namespace Channel json data; // Others. bool replied{ false }; + + public: + static void ClassInit(Channel::UnixStreamSocket* channel); + // Passed by argument. + static Channel::UnixStreamSocket* channel; }; } // namespace Channel diff --git a/worker/include/Channel/UnixStreamSocket.hpp b/worker/include/Channel/UnixStreamSocket.hpp index 0754651e96..1b8ac37f54 100644 --- a/worker/include/Channel/UnixStreamSocket.hpp +++ b/worker/include/Channel/UnixStreamSocket.hpp @@ -19,7 +19,7 @@ namespace Channel }; public: - explicit UnixStreamSocket(int fd); + explicit UnixStreamSocket(int fd, ::UnixStreamSocket::SocketRole role); public: void SetListener(Listener* listener); @@ -38,6 +38,18 @@ namespace Channel // Others. size_t msgStart{ 0 }; // Where the latest message starts. }; + + + class ChannelWrapper + { + public: + explicit ChannelWrapper(int consumerFd, int producerFd):consumerSocket(consumerFd, ::UnixStreamSocket::SocketRole::CONSUMER) + , producerSocket(producerFd, ::UnixStreamSocket::SocketRole::PRODUCER){ + } + + UnixStreamSocket consumerSocket; + UnixStreamSocket producerSocket; + }; } // namespace Channel #endif diff --git a/worker/include/RTC/RTCP/FeedbackPsFir.hpp b/worker/include/RTC/RTCP/FeedbackPsFir.hpp index 153962ec7c..65bc359d8a 100644 --- a/worker/include/RTC/RTCP/FeedbackPsFir.hpp +++ b/worker/include/RTC/RTCP/FeedbackPsFir.hpp @@ -27,7 +27,12 @@ namespace RTC { uint32_t ssrc; uint8_t sequenceNumber; +#ifdef _MSC_VER + // alignment + uint8_t reserved[3]; +#else uint32_t reserved : 24; +#endif //_MSC_VER }; public: diff --git a/worker/include/Worker.hpp b/worker/include/Worker.hpp index d1cd9f307e..970401fe09 100644 --- a/worker/include/Worker.hpp +++ b/worker/include/Worker.hpp @@ -15,7 +15,7 @@ using json = nlohmann::json; class Worker : public Channel::UnixStreamSocket::Listener, public SignalsHandler::Listener { public: - explicit Worker(Channel::UnixStreamSocket* channel); + explicit Worker(Channel::ChannelWrapper* channel); ~Worker(); private: @@ -35,7 +35,7 @@ class Worker : public Channel::UnixStreamSocket::Listener, public SignalsHandler private: // Passed by argument. - Channel::UnixStreamSocket* channel{ nullptr }; + Channel::ChannelWrapper* channel{ nullptr }; // Allocated by this. SignalsHandler* signalsHandler{ nullptr }; // Others. diff --git a/worker/include/common.hpp b/worker/include/common.hpp index 408ae5b94e..158be87b49 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -4,9 +4,9 @@ #include // std::transform(), std::find(), std::min(), std::max() #ifdef _MSC_VER #include -#undef max // https://stackoverflow.com/a/27443191/2085408 +// https://stackoverflow.com/a/27443191/2085408 +#undef max #undef min - // avoid uv/win.h: error C2628 'intptr_t' followed by 'int' is illegal #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) #include @@ -15,12 +15,11 @@ typedef SSIZE_T ssize_t; #define _SSIZE_T_ #define _SSIZE_T_DEFINED #endif - #else #include // htonl(), htons(), ntohl(), ntohs() #include // sockaddr_in, sockaddr_in6 #include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 -#endif // _WINDOWS +#endif // _MSC_VER #include // PRIu64, etc #include // size_t #include // uint8_t, etc diff --git a/worker/include/handles/UnixStreamSocket.hpp b/worker/include/handles/UnixStreamSocket.hpp index 7d0317f8e4..bed74c828e 100644 --- a/worker/include/handles/UnixStreamSocket.hpp +++ b/worker/include/handles/UnixStreamSocket.hpp @@ -15,8 +15,13 @@ class UnixStreamSocket uint8_t store[1]; }; + enum SocketRole { + CONSUMER, + PRODUCER + }; + public: - UnixStreamSocket(int fd, size_t bufferSize); + UnixStreamSocket(int fd, size_t bufferSize, SocketRole role); UnixStreamSocket& operator=(const UnixStreamSocket&) = delete; UnixStreamSocket(const UnixStreamSocket&) = delete; virtual ~UnixStreamSocket(); @@ -49,6 +54,7 @@ class UnixStreamSocket protected: // Passed by argument. size_t bufferSize{ 0 }; + SocketRole role; // Allocated by this. uint8_t* buffer{ nullptr }; // Others. diff --git a/worker/src/Channel/Request.cpp b/worker/src/Channel/Request.cpp index 8e34992a9f..1cbb3ce49b 100644 --- a/worker/src/Channel/Request.cpp +++ b/worker/src/Channel/Request.cpp @@ -57,9 +57,22 @@ namespace Channel }; // clang-format on + /* Class variables. */ + + Channel::UnixStreamSocket* Request::channel{ nullptr }; + + /* Static methods. */ + + void Request::ClassInit(Channel::UnixStreamSocket* channel) + { + MS_TRACE(); + + Request::channel = channel; + } + /* Instance methods. */ - Request::Request(Channel::UnixStreamSocket* channel, json& jsonRequest) : channel(channel) + Request::Request(json& jsonRequest) { MS_TRACE(); @@ -112,6 +125,8 @@ namespace Channel { MS_TRACE(); + MS_ASSERT(Request::channel != nullptr, "channel unset"); + MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -121,13 +136,15 @@ namespace Channel jsonResponse["id"] = this->id; jsonResponse["accepted"] = true; - this->channel->Send(jsonResponse); + Request::channel->Send(jsonResponse); } void Request::Accept(json& data) { MS_TRACE(); + MS_ASSERT(Request::channel != nullptr, "channel unset"); + MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -140,13 +157,15 @@ namespace Channel if (data.is_structured()) jsonResponse["data"] = data; - this->channel->Send(jsonResponse); + Request::channel->Send(jsonResponse); } void Request::Error(const char* reason) { MS_TRACE(); + MS_ASSERT(Request::channel != nullptr, "channel unset"); + MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -159,13 +178,15 @@ namespace Channel if (reason != nullptr) jsonResponse["reason"] = reason; - this->channel->Send(jsonResponse); + Request::channel->Send(jsonResponse); } void Request::TypeError(const char* reason) { MS_TRACE(); + MS_ASSERT(Request::channel != nullptr, "channel unset"); + MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -178,6 +199,6 @@ namespace Channel if (reason != nullptr) jsonResponse["reason"] = reason; - this->channel->Send(jsonResponse); + Request::channel->Send(jsonResponse); } } // namespace Channel diff --git a/worker/src/Channel/UnixStreamSocket.cpp b/worker/src/Channel/UnixStreamSocket.cpp index eb9db4c2c9..0230868a58 100644 --- a/worker/src/Channel/UnixStreamSocket.cpp +++ b/worker/src/Channel/UnixStreamSocket.cpp @@ -22,8 +22,8 @@ namespace Channel /* Instance methods. */ - UnixStreamSocket::UnixStreamSocket(int fd) - : ::UnixStreamSocket::UnixStreamSocket(fd, NsMessageMaxLen) + UnixStreamSocket::UnixStreamSocket(int fd, ::UnixStreamSocket::SocketRole role) + : ::UnixStreamSocket::UnixStreamSocket(fd, NsMessageMaxLen, role) { MS_TRACE_STD(); } @@ -250,7 +250,7 @@ namespace Channel try { - request = new Channel::Request(this, jsonRequest); + request = new Channel::Request(jsonRequest); } catch (const MediaSoupError& error) { diff --git a/worker/src/Worker.cpp b/worker/src/Worker.cpp index f6a26ce9d5..cbfa230660 100644 --- a/worker/src/Worker.cpp +++ b/worker/src/Worker.cpp @@ -10,12 +10,13 @@ /* Instance methods. */ -Worker::Worker(Channel::UnixStreamSocket* channel) : channel(channel) +Worker::Worker(Channel::ChannelWrapper* channel) : channel(channel) { MS_TRACE(); // Set us as Channel's listener. - this->channel->SetListener(this); + this->channel->consumerSocket.SetListener(this); + this->channel->producerSocket.SetListener(this); // Set the signals handler. this->signalsHandler = new SignalsHandler(this); @@ -118,10 +119,12 @@ RTC::Router* Worker::GetRouterFromRequest(Channel::Request* request) const return router; } -inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* /*channel*/, Channel::Request* request) +inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* socket, Channel::Request* request) { MS_TRACE(); + MS_ASSERT(socket != &this->channel->producerSocket, "Producer Socket should not used as request channel."); + MS_DEBUG_DEV( "Channel request received [method:%s, id:%" PRIu32 "]", request->method.c_str(), request->id); diff --git a/worker/src/handles/UnixStreamSocket.cpp b/worker/src/handles/UnixStreamSocket.cpp index 67cc56a294..da63fd02b6 100644 --- a/worker/src/handles/UnixStreamSocket.cpp +++ b/worker/src/handles/UnixStreamSocket.cpp @@ -69,7 +69,7 @@ inline static void onShutdown(uv_shutdown_t* req, int /*status*/) /* Instance methods. */ -UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize) : bufferSize(bufferSize) +UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, SocketRole role) : bufferSize(bufferSize), role(role) { MS_TRACE_STD(); @@ -97,17 +97,20 @@ UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize) : bufferSize(buffe MS_THROW_ERROR_STD("uv_pipe_open() failed: %s", uv_strerror(err)); } - // Start reading. - err = uv_read_start( - reinterpret_cast(this->uvHandle), - static_cast(onAlloc), - static_cast(onRead)); - - if (err != 0) + if (this->role == SocketRole::CONSUMER) { - uv_close(reinterpret_cast(this->uvHandle), static_cast(onClose)); + // Start reading. + err = uv_read_start( + reinterpret_cast(this->uvHandle), + static_cast(onAlloc), + static_cast(onRead)); + + if (err != 0) + { + uv_close(reinterpret_cast(this->uvHandle), static_cast(onClose)); - MS_THROW_ERROR_STD("uv_read_start() failed: %s", uv_strerror(err)); + MS_THROW_ERROR_STD("uv_read_start() failed: %s", uv_strerror(err)); + } } // NOTE: Don't allocate the buffer here. Instead wait for the first uv_alloc_cb(). @@ -137,11 +140,14 @@ void UnixStreamSocket::Close() // Tell the UV handle that the UnixStreamSocket has been closed. this->uvHandle->data = nullptr; - // Don't read more. - err = uv_read_stop(reinterpret_cast(this->uvHandle)); + if (this->role == SocketRole::CONSUMER) + { + // Don't read more. + err = uv_read_stop(reinterpret_cast(this->uvHandle)); - if (err != 0) - MS_ABORT("uv_read_stop() failed: %s", uv_strerror(err)); + if (err != 0) + MS_ABORT("uv_read_stop() failed: %s", uv_strerror(err)); + } // If there is no error and the peer didn't close its pipe side then close gracefully. if (!this->hasError && !this->isClosedByPeer) diff --git a/worker/src/main.cpp b/worker/src/main.cpp index d452ca87ef..fd03a60c2c 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -27,7 +27,8 @@ #include // getpid(), usleep() #endif -static constexpr int ChannelFd{ 3 }; +static constexpr int ConsumerChannelFd{ 3 }; +static constexpr int ProducerChannelFd{ 4 }; void IgnoreSignals(); @@ -47,11 +48,11 @@ int main(int argc, char* argv[]) DepLibUV::ClassInit(); // Channel socket (it will be handled and deleted by the Worker). - Channel::UnixStreamSocket* channel{ nullptr }; + Channel::ChannelWrapper* channel{ nullptr }; try { - channel = new Channel::UnixStreamSocket(ChannelFd); + channel = new Channel::ChannelWrapper(ConsumerChannelFd, ProducerChannelFd); } catch (const MediaSoupError& error) { @@ -61,7 +62,7 @@ int main(int argc, char* argv[]) } // Initialize the Logger. - Logger::ClassInit(channel); + Logger::ClassInit(&channel->producerSocket); try { @@ -111,7 +112,8 @@ int main(int argc, char* argv[]) Utils::Crypto::ClassInit(); RTC::DtlsTransport::ClassInit(); RTC::SrtpSession::ClassInit(); - Channel::Notifier::ClassInit(channel); + Channel::Notifier::ClassInit(&channel->producerSocket); + Channel::Request::ClassInit(&channel->producerSocket); // Ignore some signals. IgnoreSignals(); diff --git a/worker/test/include/helpers.hpp b/worker/test/include/helpers.hpp index 36146635f2..e18912900b 100644 --- a/worker/test/include/helpers.hpp +++ b/worker/test/include/helpers.hpp @@ -10,6 +10,11 @@ namespace helpers inline bool readBinaryFile(const char* file, uint8_t* buffer, size_t* len) { std::string filePath = "test/" + std::string(file); +#ifdef _MSC_VER + // visual studio solution and project files generated in out dir. so resources nav to parent dir. + filePath = "../" + filePath; + std::replace(filePath.begin(), filePath.end(), '/', '\\'); +#endif // _MSC_VER std::ifstream in(filePath, std::ios::ate | std::ios::binary); if (!in) From 3e57e5699847ecb2c0e13a6b3bc6b63f285c4628 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Thu, 29 Aug 2019 14:46:20 +0800 Subject: [PATCH 06/41] code style --- gulpfile.js | 2 +- lib/Worker.js | 2 +- test/test-Worker.js | 3 ++- worker/include/Channel/UnixStreamSocket.hpp | 7 ++++--- worker/include/common.hpp | 2 +- worker/include/handles/UnixStreamSocket.hpp | 3 ++- worker/src/Worker.cpp | 3 ++- worker/src/handles/UnixStreamSocket.cpp | 9 +++++---- 8 files changed, 18 insertions(+), 13 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 68e977864c..c028660025 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -74,4 +74,4 @@ gulp.task('test:make:worker', shell.task( ] )); -gulp.task('test:worker', gulp.series(os.platform() === 'win32'? 'test:win:worker' : 'test:make:worker')) +gulp.task('test:worker', gulp.series(os.platform() === 'win32'? 'test:win:worker' : 'test:make:worker')); diff --git a/lib/Worker.js b/lib/Worker.js index 55c8f5e66f..0314295b87 100644 --- a/lib/Worker.js +++ b/lib/Worker.js @@ -108,7 +108,7 @@ class Worker extends EnhancedEventEmitter { producerSocket : this._child.stdio[3], consumerSocket : this._child.stdio[4], - pid : this._pid + pid : this._pid }); // Closed flag. diff --git a/test/test-Worker.js b/test/test-Worker.js index 75fbf6ff7f..9d0e1bed0b 100644 --- a/test/test-Worker.js +++ b/test/test-Worker.js @@ -195,7 +195,8 @@ test('Worker emits "died" if worker process died unexpectedly', async () => test('worker process ignores PIPE, HUP, ALRM, USR1 and USR2 signals', async () => { - if (os.platform() === 'win32') { + if (os.platform() === 'win32') + { return; } diff --git a/worker/include/Channel/UnixStreamSocket.hpp b/worker/include/Channel/UnixStreamSocket.hpp index 1b8ac37f54..2cbe836cf1 100644 --- a/worker/include/Channel/UnixStreamSocket.hpp +++ b/worker/include/Channel/UnixStreamSocket.hpp @@ -39,12 +39,13 @@ namespace Channel size_t msgStart{ 0 }; // Where the latest message starts. }; - class ChannelWrapper { public: - explicit ChannelWrapper(int consumerFd, int producerFd):consumerSocket(consumerFd, ::UnixStreamSocket::SocketRole::CONSUMER) - , producerSocket(producerFd, ::UnixStreamSocket::SocketRole::PRODUCER){ + explicit ChannelWrapper(int consumerFd, int producerFd) + : consumerSocket(consumerFd, ::UnixStreamSocket::SocketRole::CONSUMER), + producerSocket(producerFd, ::UnixStreamSocket::SocketRole::PRODUCER) + { } UnixStreamSocket consumerSocket; diff --git a/worker/include/common.hpp b/worker/include/common.hpp index 158be87b49..ac3b29d706 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -5,7 +5,7 @@ #ifdef _MSC_VER #include // https://stackoverflow.com/a/27443191/2085408 -#undef max +#undef max #undef min // avoid uv/win.h: error C2628 'intptr_t' followed by 'int' is illegal #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) diff --git a/worker/include/handles/UnixStreamSocket.hpp b/worker/include/handles/UnixStreamSocket.hpp index bed74c828e..fb0b24f67b 100644 --- a/worker/include/handles/UnixStreamSocket.hpp +++ b/worker/include/handles/UnixStreamSocket.hpp @@ -15,7 +15,8 @@ class UnixStreamSocket uint8_t store[1]; }; - enum SocketRole { + enum SocketRole + { CONSUMER, PRODUCER }; diff --git a/worker/src/Worker.cpp b/worker/src/Worker.cpp index cbfa230660..b3024109c9 100644 --- a/worker/src/Worker.cpp +++ b/worker/src/Worker.cpp @@ -123,7 +123,8 @@ inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* socket, Channel: { MS_TRACE(); - MS_ASSERT(socket != &this->channel->producerSocket, "Producer Socket should not used as request channel."); + MS_ASSERT( + socket != &this->channel->producerSocket, "Producer Socket should not used as request channel."); MS_DEBUG_DEV( "Channel request received [method:%s, id:%" PRIu32 "]", request->method.c_str(), request->id); diff --git a/worker/src/handles/UnixStreamSocket.cpp b/worker/src/handles/UnixStreamSocket.cpp index da63fd02b6..f34728f5c5 100644 --- a/worker/src/handles/UnixStreamSocket.cpp +++ b/worker/src/handles/UnixStreamSocket.cpp @@ -69,7 +69,8 @@ inline static void onShutdown(uv_shutdown_t* req, int /*status*/) /* Instance methods. */ -UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, SocketRole role) : bufferSize(bufferSize), role(role) +UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, SocketRole role) + : bufferSize(bufferSize), role(role) { MS_TRACE_STD(); @@ -101,9 +102,9 @@ UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, SocketRole role) : { // Start reading. err = uv_read_start( - reinterpret_cast(this->uvHandle), - static_cast(onAlloc), - static_cast(onRead)); + reinterpret_cast(this->uvHandle), + static_cast(onAlloc), + static_cast(onRead)); if (err != 0) { From 12b6a3cc877148e44a1d61c61055f9bea81c5112 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 10:29:41 +0800 Subject: [PATCH 07/41] add explicit key word --- worker/include/Channel/Request.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worker/include/Channel/Request.hpp b/worker/include/Channel/Request.hpp index 4fea1c39e8..002ab4e976 100644 --- a/worker/include/Channel/Request.hpp +++ b/worker/include/Channel/Request.hpp @@ -67,7 +67,7 @@ namespace Channel static std::unordered_map string2MethodId; public: - Request(json& jsonRequest); + explicit Request(json& jsonRequest); virtual ~Request(); void Accept(); From 283351a5f397ee14ed67ac4180ef962fbfcbdc90 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 10:31:52 +0800 Subject: [PATCH 08/41] move getopt to deps --- worker/{opt => deps/getopt}/getopt.cpp | 5 ++--- worker/deps/getopt/getopt.gyp | 18 ++++++++++++++++++ worker/{include/opt => deps/getopt}/getopt.h | 0 worker/mediasoup-worker.gyp | 5 +---- worker/src/Settings.cpp | 4 ---- 5 files changed, 21 insertions(+), 11 deletions(-) rename worker/{opt => deps/getopt}/getopt.cpp (99%) create mode 100644 worker/deps/getopt/getopt.gyp rename worker/{include/opt => deps/getopt}/getopt.h (100%) diff --git a/worker/opt/getopt.cpp b/worker/deps/getopt/getopt.cpp similarity index 99% rename from worker/opt/getopt.cpp rename to worker/deps/getopt/getopt.cpp index fbd2182fc0..ec75c4c76c 100644 --- a/worker/opt/getopt.cpp +++ b/worker/deps/getopt/getopt.cpp @@ -29,7 +29,7 @@ Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ -#include "opt/getopt.h" +#include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, @@ -799,14 +799,13 @@ int main(int argc, char **argv) { - int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; - c = getopt(argc, argv, "abc:d:0123456789"); + int c = getopt(argc, argv, "abc:d:0123456789"); if (c == -1) break; diff --git a/worker/deps/getopt/getopt.gyp b/worker/deps/getopt/getopt.gyp new file mode 100644 index 0000000000..dfb7cd5966 --- /dev/null +++ b/worker/deps/getopt/getopt.gyp @@ -0,0 +1,18 @@ +{ + 'targets': + [ + { + 'target_name': 'getopt', + 'type': 'static_library', + 'sources': + [ + 'getopt.h', + 'getopt.cpp' + ], + 'direct_dependent_settings': + { + 'include_dirs': ['.'] + }, + } + ] +} \ No newline at end of file diff --git a/worker/include/opt/getopt.h b/worker/deps/getopt/getopt.h similarity index 100% rename from worker/include/opt/getopt.h rename to worker/deps/getopt/getopt.h diff --git a/worker/mediasoup-worker.gyp b/worker/mediasoup-worker.gyp index f6048d0940..56def0fdb2 100644 --- a/worker/mediasoup-worker.gyp +++ b/worker/mediasoup-worker.gyp @@ -272,10 +272,7 @@ }], [ 'OS == "win"', { - 'sources': [ - 'include/opt/getopt.h', - 'opt/getopt.cpp' - ] + 'dependencies': [ 'deps/getopt/getopt.gyp:getopt' ] }], [ 'OS != "win"', { diff --git a/worker/src/Settings.cpp b/worker/src/Settings.cpp index d35d88a7e3..7a5674d3d3 100644 --- a/worker/src/Settings.cpp +++ b/worker/src/Settings.cpp @@ -10,13 +10,9 @@ #include #include // std::ostream_iterator #include // std::ostringstream -#ifdef _MSC_VER -#include "opt/getopt.h" -#else extern "C" { #include } -#endif // _MSC_VER /* Class variables. */ From a15863c962f854bc369341f0cf8e99d7a12f67b1 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 10:57:08 +0800 Subject: [PATCH 09/41] single quotes --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index fda983616f..d390f63d0c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -173,6 +173,6 @@ module.exports = 'strict': 2, 'valid-typeof': 2, 'yoda': 2, - "linebreak-style": 0 + 'linebreak-style': 0 } }; From b86a32f78305ff9ba831938c185e7132a1b44f7f Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 10:58:15 +0800 Subject: [PATCH 10/41] pyc explicit path --- .gitignore | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3f160e6b77..4695e5b115 100644 --- a/.gitignore +++ b/.gitignore @@ -23,8 +23,8 @@ # Mac Stuff. .DS_Store -# Win Stuff -configure.pyc +# python win generated Stuff. +/worker/scripts/configure.pyc -# VS stuff -/worker/.vs/ \ No newline at end of file +# VS stuff. +/worker/.vs/ From 9a66008f3876cd38c758af2f369de4321166130d Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 11:32:13 +0800 Subject: [PATCH 11/41] delete unused dep --- package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/package.json b/package.json index f02e7575f0..4cfd7ec97b 100644 --- a/package.json +++ b/package.json @@ -46,11 +46,7 @@ "uuid": "^3.3.2", "gulp": "^4.0.2", "gulp-clang-format": "^1.0.27", - "gulp-eslint": "^6.0.0", - "gulp-rename": "^1.4.0", - "gulp-replace": "^1.0.0", - "gulp-shell": "^0.6.5", - "gulp-touch-cmd": "0.0.1" + "gulp-shell": "^0.6.5" }, "devDependencies": { "eslint": "^6.1.0", From c20fb5bafeefc586d481d65733e2f822107f8b4d Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 11:34:06 +0800 Subject: [PATCH 12/41] log text & code style --- lib/Channel.js | 8 ++++---- test/test-Worker.js | 4 +--- worker/mediasoup-worker.gyp | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/Channel.js b/lib/Channel.js index 892f2a7d2b..b1864a1f69 100644 --- a/lib/Channel.js +++ b/lib/Channel.js @@ -148,11 +148,11 @@ class Channel extends EnhancedEventEmitter } }); - this._consumerSocket.on('end', () => this._logger.debug('Consumer channel ended by the worker process')); - this._consumerSocket.on('error', (error) => this._logger.error('Consumer channel error: %s', String(error))); + this._consumerSocket.on('end', () => this._logger.debug('Consumer Channel ended by the worker process')); + this._consumerSocket.on('error', (error) => this._logger.error('Consumer Channel error: %s', String(error))); - this._producerSocket.on('end', () => this._logger.debug('Producer channel ended by the worker process')); - this._producerSocket.on('error', (error) => this._logger.error('Producer channel error: %s', String(error))); + this._producerSocket.on('end', () => this._logger.debug('Producer Channel ended by the worker process')); + this._producerSocket.on('error', (error) => this._logger.error('Producer Channel error: %s', String(error))); } /** diff --git a/test/test-Worker.js b/test/test-Worker.js index 9d0e1bed0b..08dd9da35e 100644 --- a/test/test-Worker.js +++ b/test/test-Worker.js @@ -1,9 +1,9 @@ +const os = require('os'); const process = require('process'); const { toBeType } = require('jest-tobetype'); const mediasoup = require('../'); const { createWorker, observer } = mediasoup; const { InvalidStateError } = require('../lib/errors'); -const os = require('os'); expect.extend({ toBeType }); @@ -196,9 +196,7 @@ test('Worker emits "died" if worker process died unexpectedly', async () => test('worker process ignores PIPE, HUP, ALRM, USR1 and USR2 signals', async () => { if (os.platform() === 'win32') - { return; - } worker = await createWorker({ logLevel: 'warn' }); diff --git a/worker/mediasoup-worker.gyp b/worker/mediasoup-worker.gyp index 56def0fdb2..af7cd729d6 100644 --- a/worker/mediasoup-worker.gyp +++ b/worker/mediasoup-worker.gyp @@ -303,7 +303,7 @@ # C++ source files. 'src/main.cpp' ], - # handle multi files with same name + # handle multi files with same name. # https://stackoverflow.com/a/22936230/2085408 # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile 'msvs_settings': { @@ -367,7 +367,7 @@ '--coverage' ] }, - # handle multi files with same name + # handle multi files with same name. # https://stackoverflow.com/a/22936230/2085408 # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile 'msvs_settings': { @@ -435,7 +435,7 @@ [ 'fuzzer/include' ], - # handle multi files with same name + # handle multi files with same name. # https://stackoverflow.com/a/22936230/2085408 # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile 'msvs_settings': { From 850761fc93ec23986a0e61f86c2d36a2600134c9 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 11:37:28 +0800 Subject: [PATCH 13/41] rename SocketRole to role --- worker/include/Channel/UnixStreamSocket.hpp | 10 ++++++---- worker/include/handles/UnixStreamSocket.hpp | 10 +++++----- worker/src/Channel/UnixStreamSocket.cpp | 2 +- worker/src/handles/UnixStreamSocket.cpp | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/worker/include/Channel/UnixStreamSocket.hpp b/worker/include/Channel/UnixStreamSocket.hpp index 2cbe836cf1..d30af13833 100644 --- a/worker/include/Channel/UnixStreamSocket.hpp +++ b/worker/include/Channel/UnixStreamSocket.hpp @@ -19,7 +19,7 @@ namespace Channel }; public: - explicit UnixStreamSocket(int fd, ::UnixStreamSocket::SocketRole role); + explicit UnixStreamSocket(int fd, ::UnixStreamSocket::Role role); public: void SetListener(Listener* listener); @@ -42,12 +42,14 @@ namespace Channel class ChannelWrapper { public: - explicit ChannelWrapper(int consumerFd, int producerFd) - : consumerSocket(consumerFd, ::UnixStreamSocket::SocketRole::CONSUMER), - producerSocket(producerFd, ::UnixStreamSocket::SocketRole::PRODUCER) + ChannelWrapper(int consumerFd, int producerFd) + : consumerSocket(consumerFd, ::UnixStreamSocket::Role::CONSUMER), + producerSocket(producerFd, ::UnixStreamSocket::Role::PRODUCER) { } + public: + // Passed by argument. UnixStreamSocket consumerSocket; UnixStreamSocket producerSocket; }; diff --git a/worker/include/handles/UnixStreamSocket.hpp b/worker/include/handles/UnixStreamSocket.hpp index fb0b24f67b..442b44c1c5 100644 --- a/worker/include/handles/UnixStreamSocket.hpp +++ b/worker/include/handles/UnixStreamSocket.hpp @@ -15,14 +15,14 @@ class UnixStreamSocket uint8_t store[1]; }; - enum SocketRole + enum class Role { - CONSUMER, - PRODUCER + PRODUCER = 1, + CONSUMER }; public: - UnixStreamSocket(int fd, size_t bufferSize, SocketRole role); + UnixStreamSocket(int fd, size_t bufferSize, UnixStreamSocket::Role role); UnixStreamSocket& operator=(const UnixStreamSocket&) = delete; UnixStreamSocket(const UnixStreamSocket&) = delete; virtual ~UnixStreamSocket(); @@ -55,7 +55,7 @@ class UnixStreamSocket protected: // Passed by argument. size_t bufferSize{ 0 }; - SocketRole role; + UnixStreamSocket::Role role; // Allocated by this. uint8_t* buffer{ nullptr }; // Others. diff --git a/worker/src/Channel/UnixStreamSocket.cpp b/worker/src/Channel/UnixStreamSocket.cpp index 0230868a58..2825afe1fb 100644 --- a/worker/src/Channel/UnixStreamSocket.cpp +++ b/worker/src/Channel/UnixStreamSocket.cpp @@ -22,7 +22,7 @@ namespace Channel /* Instance methods. */ - UnixStreamSocket::UnixStreamSocket(int fd, ::UnixStreamSocket::SocketRole role) + UnixStreamSocket::UnixStreamSocket(int fd, ::UnixStreamSocket::Role role) : ::UnixStreamSocket::UnixStreamSocket(fd, NsMessageMaxLen, role) { MS_TRACE_STD(); diff --git a/worker/src/handles/UnixStreamSocket.cpp b/worker/src/handles/UnixStreamSocket.cpp index f34728f5c5..9f9343c6ab 100644 --- a/worker/src/handles/UnixStreamSocket.cpp +++ b/worker/src/handles/UnixStreamSocket.cpp @@ -69,7 +69,7 @@ inline static void onShutdown(uv_shutdown_t* req, int /*status*/) /* Instance methods. */ -UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, SocketRole role) +UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, UnixStreamSocket::Role role) : bufferSize(bufferSize), role(role) { MS_TRACE_STD(); @@ -98,7 +98,7 @@ UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, SocketRole role) MS_THROW_ERROR_STD("uv_pipe_open() failed: %s", uv_strerror(err)); } - if (this->role == SocketRole::CONSUMER) + if (this->role == UnixStreamSocket::Role::CONSUMER) { // Start reading. err = uv_read_start( @@ -141,7 +141,7 @@ void UnixStreamSocket::Close() // Tell the UV handle that the UnixStreamSocket has been closed. this->uvHandle->data = nullptr; - if (this->role == SocketRole::CONSUMER) + if (this->role == UnixStreamSocket::Role::CONSUMER) { // Don't read more. err = uv_read_stop(reinterpret_cast(this->uvHandle)); From 6a1a92716f0667a3d7955bc1d911acb44be20750 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 11:38:43 +0800 Subject: [PATCH 14/41] log text & code style --- worker/src/Worker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worker/src/Worker.cpp b/worker/src/Worker.cpp index b3024109c9..b98fc4a432 100644 --- a/worker/src/Worker.cpp +++ b/worker/src/Worker.cpp @@ -124,7 +124,7 @@ inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* socket, Channel: MS_TRACE(); MS_ASSERT( - socket != &this->channel->producerSocket, "Producer Socket should not used as request channel."); + socket != &this->channel->producerSocket, "Producer Socket should not used as request channel"); MS_DEBUG_DEV( "Channel request received [method:%s, id:%" PRIu32 "]", request->method.c_str(), request->id); From af693c42645552cf5a2a79425acdb74b12db9f89 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 11:46:33 +0800 Subject: [PATCH 15/41] replace _MSC_VER with _WIN32 for better compatibility --- worker/include/RTC/RTCP/FeedbackPsFir.hpp | 7 +++---- worker/include/Utils.hpp | 4 ++-- worker/include/common.hpp | 4 ++-- worker/src/Logger.cpp | 2 +- worker/src/Utils/File.cpp | 4 ++-- worker/src/main.cpp | 4 ++-- worker/test/include/helpers.hpp | 6 ++---- 7 files changed, 14 insertions(+), 17 deletions(-) diff --git a/worker/include/RTC/RTCP/FeedbackPsFir.hpp b/worker/include/RTC/RTCP/FeedbackPsFir.hpp index 65bc359d8a..4cc096a299 100644 --- a/worker/include/RTC/RTCP/FeedbackPsFir.hpp +++ b/worker/include/RTC/RTCP/FeedbackPsFir.hpp @@ -27,12 +27,11 @@ namespace RTC { uint32_t ssrc; uint8_t sequenceNumber; -#ifdef _MSC_VER - // alignment - uint8_t reserved[3]; +#ifdef _WIN32 + uint8_t reserved[3]; // Alignment. #else uint32_t reserved : 24; -#endif //_MSC_VER +#endif }; public: diff --git a/worker/include/Utils.hpp b/worker/include/Utils.hpp index 8df9f7aa4e..e15b730c30 100644 --- a/worker/include/Utils.hpp +++ b/worker/include/Utils.hpp @@ -6,12 +6,12 @@ #include #include // std::memcmp(), std::memcpy() #include -#ifdef _MSC_VER +#ifdef _WIN32 #include // https://stackoverflow.com/a/24550632/2085408 #include #define __builtin_popcount __popcnt -#endif // _WIN32 +#endif namespace Utils { diff --git a/worker/include/common.hpp b/worker/include/common.hpp index ac3b29d706..d17a1c9cf1 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -2,7 +2,7 @@ #define MS_COMMON_HPP #include // std::transform(), std::find(), std::min(), std::max() -#ifdef _MSC_VER +#ifdef _WIN32 #include // https://stackoverflow.com/a/27443191/2085408 #undef max @@ -19,7 +19,7 @@ typedef SSIZE_T ssize_t; #include // htonl(), htons(), ntohl(), ntohs() #include // sockaddr_in, sockaddr_in6 #include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 -#endif // _MSC_VER +#endif #include // PRIu64, etc #include // size_t #include // uint8_t, etc diff --git a/worker/src/Logger.cpp b/worker/src/Logger.cpp index ede7e28308..ded5f69b97 100644 --- a/worker/src/Logger.cpp +++ b/worker/src/Logger.cpp @@ -2,7 +2,7 @@ // #define MS_LOG_DEV #include "Logger.hpp" -#ifndef _MSC_VER +#ifndef _WIN32 #include // getpid() #endif diff --git a/worker/src/Utils/File.cpp b/worker/src/Utils/File.cpp index 2e0a30e955..a19da52df5 100644 --- a/worker/src/Utils/File.cpp +++ b/worker/src/Utils/File.cpp @@ -6,13 +6,13 @@ #include "Utils.hpp" #include #include // stat() -#ifdef _MSC_VER +#ifdef _WIN32 #include #define __S_ISTYPE(mode, mask) (((mode)&_S_IFMT) == (mask)) #define S_ISREG(mode) __S_ISTYPE((mode), _S_IFREG) #else #include // access(), R_OK -#endif // _WINDOWS +#endif namespace Utils { diff --git a/worker/src/main.cpp b/worker/src/main.cpp index fd03a60c2c..19b1b96124 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -21,7 +21,7 @@ #include // std::cerr, std::endl #include #include -#ifdef _MSC_VER +#ifdef _WIN32 #define usleep Sleep #else #include // getpid(), usleep() @@ -143,7 +143,7 @@ int main(int argc, char* argv[]) void IgnoreSignals() { -#ifndef _MSC_VER +#ifndef _WIN32 MS_TRACE(); int err; diff --git a/worker/test/include/helpers.hpp b/worker/test/include/helpers.hpp index e18912900b..69160ca080 100644 --- a/worker/test/include/helpers.hpp +++ b/worker/test/include/helpers.hpp @@ -10,11 +10,9 @@ namespace helpers inline bool readBinaryFile(const char* file, uint8_t* buffer, size_t* len) { std::string filePath = "test/" + std::string(file); -#ifdef _MSC_VER - // visual studio solution and project files generated in out dir. so resources nav to parent dir. - filePath = "../" + filePath; +#ifdef _WIN32 std::replace(filePath.begin(), filePath.end(), '/', '\\'); -#endif // _MSC_VER +#endif std::ifstream in(filePath, std::ios::ate | std::ios::binary); if (!in) From d3f3a4cbd24bf2452789c2551c85d75f1b026384 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 11:59:27 +0800 Subject: [PATCH 16/41] add public keyword to separate method and var --- worker/include/Channel/Request.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/worker/include/Channel/Request.hpp b/worker/include/Channel/Request.hpp index 002ab4e976..096bb25254 100644 --- a/worker/include/Channel/Request.hpp +++ b/worker/include/Channel/Request.hpp @@ -86,6 +86,8 @@ namespace Channel public: static void ClassInit(Channel::UnixStreamSocket* channel); + + public: // Passed by argument. static Channel::UnixStreamSocket* channel; }; From cbc1b1d6ae035fd868354a0a3036c3538e70ea8d Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 30 Aug 2019 14:06:23 +0800 Subject: [PATCH 17/41] Generate sln under worker directory for unifying test:woker logic --- .gitignore | 8 ++++++++ gulpfile.js | 4 ++-- worker/mediasoup-worker.gyp | 35 +++++++++++++++-------------------- worker/scripts/configure.py | 5 ----- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 4695e5b115..761ee961c9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,10 @@ # gyp generated stuff. /worker/out/ /worker/**/*.xcodeproj/ +/worker/**/*.sln +/worker/**/*.vcxproj +/worker/**/*.vcxproj.filters +/worker/**/*.vcxproj.user # clang-fuzzer stuff is too big. /worker/deps/clang-fuzzer @@ -26,5 +30,9 @@ # python win generated Stuff. /worker/scripts/configure.pyc +# vistual studio generated Stuff. +/worker/**/Debug/ +/worker/**/Release/ + # VS stuff. /worker/.vs/ diff --git a/gulpfile.js b/gulpfile.js index c028660025..04477e4a57 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -43,8 +43,8 @@ gulp.task('format:worker', () => gulp.task('win:build', shell.task( [ 'echo build for windows', - 'cd worker && python ./scripts/configure.py --format=msvs', - `MSBuild ./worker/out/mediasoup-worker.sln /p:Configuration=${process.env.MEDIASOUP_BUILDTYPE === 'Debug' ?'Debug' : 'Release'} -t:mediasoup-worker ` + 'python ./worker/scripts/configure.py --format=msvs', + `MSBuild ./worker/mediasoup-worker.sln /p:Configuration=${process.env.MEDIASOUP_BUILDTYPE === 'Debug' ?'Debug' : 'Release'} -t:mediasoup-worker ` ], { verbose : true diff --git a/worker/mediasoup-worker.gyp b/worker/mediasoup-worker.gyp index af7cd729d6..ee83584cd8 100644 --- a/worker/mediasoup-worker.gyp +++ b/worker/mediasoup-worker.gyp @@ -272,7 +272,20 @@ }], [ 'OS == "win"', { - 'dependencies': [ 'deps/getopt/getopt.gyp:getopt' ] + 'dependencies': [ 'deps/getopt/getopt.gyp:getopt' ], + + # handle multi files with same name. + # https://stackoverflow.com/a/22936230/2085408 + # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile + 'msvs_settings': { + 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, + }, + + # Output Directory setting for msvc. + # https://github.com/nodejs/node-gyp/issues/1242#issuecomment-310921441 + 'msvs_configuration_attributes': { + 'OutputDirectory': '$(SolutionDir)\\out\\$(Configuration)\\' + } }], [ 'OS != "win"', { @@ -302,13 +315,7 @@ [ # C++ source files. 'src/main.cpp' - ], - # handle multi files with same name. - # https://stackoverflow.com/a/22936230/2085408 - # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile - 'msvs_settings': { - 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, - } + ] }, { 'target_name': 'mediasoup-worker-test', @@ -366,12 +373,6 @@ 'OTHER_LDFLAGS': [ '--coverage' ] - }, - # handle multi files with same name. - # https://stackoverflow.com/a/22936230/2085408 - # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile - 'msvs_settings': { - 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, } }, { @@ -435,12 +436,6 @@ [ 'fuzzer/include' ], - # handle multi files with same name. - # https://stackoverflow.com/a/22936230/2085408 - # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile - 'msvs_settings': { - 'VCCLCompilerTool': { 'ObjectFile': ['$(IntDir)\%(RelativeDir)\%(Filename).obj'], }, - }, 'conditions': [ diff --git a/worker/scripts/configure.py b/worker/scripts/configure.py index de878667b6..01dfcca235 100755 --- a/worker/scripts/configure.py +++ b/worker/scripts/configure.py @@ -85,11 +85,6 @@ def run_gyp(args): args.append('-Dclang=%d' % int(is_clang)) if is_clang == False and major == 4 and minor <= 8: raise RuntimeError('gcc <= 4.8 not supported, please upgrade your gcc') - else: - if 'ninja' not in args: - args.extend(['-Goutput_dir=' + output_dir]) - args.extend(['--generator-output', output_dir]) - if not any(a.startswith('-Dhost_arch=') for a in args): args.append('-Dhost_arch=%s' % host_arch()) From e489d3b16f252321d85ae49e99c67c3ca1e14ede Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sun, 1 Sep 2019 10:44:35 +0800 Subject: [PATCH 18/41] add "getopt" entry in worker/scripts/get-dep.sh --- worker/deps/getopt/getopt.cpp | 861 ----------------------- worker/deps/getopt/getopt.gyp | 12 +- worker/deps/getopt/getopt.h | 101 --- worker/deps/getopt/getopt/.gitignore | 8 + worker/deps/getopt/getopt/CMakeLists.txt | 23 + worker/deps/getopt/getopt/LICENSE | 54 ++ worker/deps/getopt/getopt/README.md | 63 ++ worker/deps/getopt/getopt/src/getopt.c | 562 +++++++++++++++ worker/deps/getopt/getopt/src/getopt.h | 105 +++ worker/scripts/get-dep.sh | 12 + 10 files changed, 835 insertions(+), 966 deletions(-) delete mode 100644 worker/deps/getopt/getopt.cpp delete mode 100644 worker/deps/getopt/getopt.h create mode 100644 worker/deps/getopt/getopt/.gitignore create mode 100644 worker/deps/getopt/getopt/CMakeLists.txt create mode 100644 worker/deps/getopt/getopt/LICENSE create mode 100644 worker/deps/getopt/getopt/README.md create mode 100644 worker/deps/getopt/getopt/src/getopt.c create mode 100644 worker/deps/getopt/getopt/src/getopt.h diff --git a/worker/deps/getopt/getopt.cpp b/worker/deps/getopt/getopt.cpp deleted file mode 100644 index ec75c4c76c..0000000000 --- a/worker/deps/getopt/getopt.cpp +++ /dev/null @@ -1,861 +0,0 @@ -#include -#include -#include - -#define getpid() GetCurrentProcessId() - -#ifndef _ -/* This is for other GNU distributions with internationalized messages. -When compiling libc, the _ macro is predefined. */ -#ifdef NEVER_HAVE_LIBINTL_H -# include -# define _(msgid) gettext (msgid) -#else -# define _(msgid) (msgid) -#endif -#endif - -/* This version of `getopt' appears to the caller like standard Unix `getopt' -but it behaves differently for the user, since it allows the user -to intersperse the options with the other arguments. - -As `getopt' works, it permutes the elements of ARGV so that, -when it is done, all the options precede everything else. Thus -all application programs are extended to handle flexible argument order. - -Setting the environment variable POSIXLY_CORRECT disables permutation. -Then the behavior is completely standard. - -GNU application programs can use a third alternative mode in which -they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. -When `getopt' finds an option that takes an argument, -the argument value is returned here. -Also, when `ordering' is RETURN_IN_ORDER, -each non-option ARGV-element is returned here. */ - -char *optarg = NULL; - -/* Index in ARGV of the next element to be scanned. -This is used for communication to and from the caller -and for communication between successive calls to `getopt'. - -On entry to `getopt', zero means this is the first call; initialize. - -When `getopt' returns -1, this is the index of the first of the -non-option elements that the caller should itself scan. - -Otherwise, `optind' communicates from one call to the next -how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Formerly, initialization of getopt depended on optind==0, which -causes problems with re-calling getopt as programs generally don't -know that. */ - -int __getopt_initialized = 0; - -/* The next char to be scanned in the option-element -in which the last option character we returned was found. -This allows us to pick up the scan where we left off. - -If this is zero, or a null string, it means resume the scan -by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message -for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. -This must be initialized on some systems to avoid linking in the -system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - -If the caller did not specify anything, -the default is REQUIRE_ORDER if the environment variable -POSIXLY_CORRECT is defined, PERMUTE otherwise. - -REQUIRE_ORDER means don't recognize them as options; -stop option processing when the first non-option is seen. -This is what Unix does. -This mode of operation is selected by either setting the environment -variable POSIXLY_CORRECT, or using `+' as the first character -of the list of option characters. - -PERMUTE is the default. We permute the contents of ARGV as we scan, -so that eventually all the non-options are at the end. This allows options -to be given in any order, even with programs that were not written to -expect this. - -RETURN_IN_ORDER is an option available to programs that were written -to expect options and other ARGV-elements in any order and that care about -the ordering of the two. We describe each non-option ARGV-element -as if it were the argument of an option with character code 1. -Using `-' as the first character of the list of option characters -selects this mode of operation. - -The special argument `--' forces an end of option-scanning regardless -of the value of `ordering'. In the case of RETURN_IN_ORDER, only -`--' can cause `getopt' to return -1 with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -/* Avoid depending on library functions or files -whose names are inconsistent. */ - -char *getenv(); - -static char * -my_index(const char *str, int chr) -{ - while (*str) - { - if (*str == chr) - return (char *)str; - str++; - } - return 0; -} - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have -been skipped. `first_nonopt' is the index in ARGV of the first of them; -`last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - - -# define SWAP_FLAGS(ch1, ch2) - -/* Exchange two adjacent subsequences of ARGV. -One subsequence is elements [first_nonopt,last_nonopt) -which contains all the non-options that have been skipped so far. -The other is elements [last_nonopt,optind), which contains all -the options processed since those non-options were skipped. - -`first_nonopt' and `last_nonopt' are relocated so that they describe -the new indices of the non-options in ARGV after they are moved. */ - - - -static void -exchange(char **argv) - -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - - - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS(bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize(int argc, - char *const *argv, - const char *optstring) -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind; - - nextchar = NULL; - - // posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - //else if (posixly_correct != NULL) - // ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - - - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters -given in OPTSTRING. - -If an element of ARGV starts with '-', and is not exactly "-" or "--", -then it is an option element. The characters of this element -(aside from the initial '-') are option characters. If `getopt' -is called repeatedly, it returns successively each of the option characters -from each of the option elements. - -If `getopt' finds another option character, it returns that character, -updating `optind' and `nextchar' so that the next call to `getopt' can -resume the scan with the following option character or ARGV-element. - -If there are no more option characters, `getopt' returns -1. -Then `optind' is the index in ARGV of the first ARGV-element -that is not an option. (The ARGV-elements have been permuted -so that those that are not options now come last.) - -OPTSTRING is a string containing the legitimate option characters. -If an option character is seen that is not listed in OPTSTRING, -return '?' after printing an error message. If you set `opterr' to -zero, the error message is suppressed but we still return '?'. - -If a char in OPTSTRING is followed by a colon, that means it wants an arg, -so the following text in the same ARGV-element, or the text of the following -ARGV-element, is returned in `optarg'. Two colons mean an option that -wants an optional arg; if there is text in the current ARGV-element, -it is returned in `optarg', otherwise `optarg' is set to zero. - -If OPTSTRING starts with `-' or `+', it requests different methods of -handling the non-option ARGV-elements. -See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - -Long-named options begin with `--' instead of `-'. -Their names may be abbreviated as long as the abbreviation is unique -or is an exact match for some defined option. If they have an -argument, it follows the option name in the same ARGV-element, separated -from the option name by a `=', or else the in next ARGV-element. -When `getopt' finds a long-named option, it returns 0 if that option's -`flag' field is nonzero, the value of the option's `val' field -if the `flag' field is zero. - -The elements of ARGV aren't really const, because we permute them. -But we pretend they're const in the prototype to be compatible -with other systems. - -LONGOPTS is a vector of `struct option' terminated by an -element containing a name which is zero. - -LONGIND returns the index in LONGOPT of the long-named option found. -It is only valid when a long-named option has been found by the most -recent call. - -If LONG_ONLY is nonzero, '-' as well as '--' can introduce -long-named options. */ - -int -_getopt_internal(int argc, - char *const *argv, - const char *optstring, - const struct option *longopts, - int *longind, - int long_only) -{ - optarg = NULL; - - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize(argc, argv, optstring); - __getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange((char **)argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp(argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange((char **)argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only - && (argv[optind][2] - || !my_index(optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int)(nameend - nextchar) - == (unsigned int)strlen(p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf(stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen(nextchar); - optind++; - optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf(stderr, - _ - ("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf(stderr, - _ - ("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); - - nextchar += strlen(nextchar); - - optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf(stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen(nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen(nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index(optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf(stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); - else - /* +option or -option */ - fprintf(stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index(optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c); - else - fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; - nameend++) - /* Do nothing. */; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int)(nameend - nextchar) == strlen(p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (opterr) - fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen(nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - fprintf(stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); - - nextchar += strlen(nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf(stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen(nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen(nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt(int argc, - char *const *argv, - const char *optstring) -{ - return _getopt_internal(argc, argv, optstring, - (const struct option *) 0, (int *)0, 0); -} - - -int -getopt_long(int argc, char *const * argv, const char * options, - const struct option * long_options, int *opt_index) -{ - return _getopt_internal(argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. -If an option that starts with '-' (not '--') doesn't match a long option, -but does match a short option, it is parsed as a short option -instead. */ - -int -getopt_long_only(int argc, char *const * argv, const char * options, - const struct option * long_options, int *opt_index) -{ - return _getopt_internal(argc, argv, options, long_options, opt_index, 1); -} - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing -the above definition of `getopt'. */ - -int -main(int argc, - char **argv) -{ - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - int c = getopt(argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf("option %c\n", c); - break; - - case 'a': - printf("option a\n"); - break; - - case 'b': - printf("option b\n"); - break; - - case 'c': - printf("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf("non-option ARGV-elements: "); - while (optind < argc) - printf("%s ", argv[optind++]); - printf("\n"); - } - - return 0; -} - -#endif /* TEST */ diff --git a/worker/deps/getopt/getopt.gyp b/worker/deps/getopt/getopt.gyp index dfb7cd5966..fa63de7123 100644 --- a/worker/deps/getopt/getopt.gyp +++ b/worker/deps/getopt/getopt.gyp @@ -6,13 +6,17 @@ 'type': 'static_library', 'sources': [ - 'getopt.h', - 'getopt.cpp' + 'getopt/src/getopt.h', + 'getopt/src/getopt.c' + ], + 'include_dirs': + [ + 'getopt/src/' ], 'direct_dependent_settings': { - 'include_dirs': ['.'] + 'include_dirs': ['getopt/src/'] }, } ] -} \ No newline at end of file +} diff --git a/worker/deps/getopt/getopt.h b/worker/deps/getopt/getopt.h deleted file mode 100644 index 5ff8bee32c..0000000000 --- a/worker/deps/getopt/getopt.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef _GETOPT_H -#define _GETOPT_H - -#ifdef __cplusplus - -extern "C" { -#endif - - /* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here.*/ - - extern char *optarg; - - /* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far.*/ - - extern int optind; - - /* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options.*/ - - extern int opterr; - - /* Set to an option character which was unrecognized.*/ - - extern int optopt; - - /* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument(or 0) if the option does not take an argument, - required_argument(or 1) if the option requires an argument, - optional_argument(or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one).For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field.*/ - - struct option - { -#if defined (__STDC__) && __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int.*/ - int has_arg; - int *flag; - int val; - }; - - /* Names for the values of the `has_arg' field of `struct option'.*/ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - - extern int getopt_long(int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); - extern int getopt_long_only(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - - /* Internal only.Users should not call this directly.*/ - extern int _getopt_internal(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); - extern int - getopt(int argc, - char *const *argv, - const char *optstring); - - #ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/worker/deps/getopt/getopt/.gitignore b/worker/deps/getopt/getopt/.gitignore new file mode 100644 index 0000000000..5500d01460 --- /dev/null +++ b/worker/deps/getopt/getopt/.gitignore @@ -0,0 +1,8 @@ +CMakeCache.txt +CMakeFiles +Makefile +cmake_install.cmake +install_manifest.txt +build +*.lib +*.pdb diff --git a/worker/deps/getopt/getopt/CMakeLists.txt b/worker/deps/getopt/getopt/CMakeLists.txt new file mode 100644 index 0000000000..663f0c02e3 --- /dev/null +++ b/worker/deps/getopt/getopt/CMakeLists.txt @@ -0,0 +1,23 @@ +PROJECT(wingetopt) +cmake_minimum_required(VERSION 2.8) + +option(BUILD_SHARED_LIBS "Build the shared library" OFF) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) + +add_definitions(-D_CRT_SECURE_NO_WARNINGS) + +if(BUILD_SHARED_LIBS) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + add_definitions(-DBUILDING_WINGETOPT_DLL -DWINGETOPT_SHARED_LIB) +endif() + +add_library(wingetopt src/getopt.c src/getopt.h) + +install(FILES src/getopt.h DESTINATION include) + +install(TARGETS wingetopt + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) + diff --git a/worker/deps/getopt/getopt/LICENSE b/worker/deps/getopt/getopt/LICENSE new file mode 100644 index 0000000000..b1ded6d834 --- /dev/null +++ b/worker/deps/getopt/getopt/LICENSE @@ -0,0 +1,54 @@ +#### AUTHORS: + +* Todd C. Miller +* The NetBSD Foundation, Inc. +* Alexei Kasatkin is the author of trivial CMakeLists.txt, build script itself is Public Domain + +#### LICENSE + + Copyright (c) 2002 Todd C. Miller + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Sponsored in part by the Defense Advanced Research Projects + Agency (DARPA) and Air Force Research Laboratory, Air Force + Materiel Command, USAF, under agreement number F39502-99-1-0512. + +*** + + Copyright (c) 2000 The NetBSD Foundation, Inc. + All rights reserved. + + This code is derived from software contributed to The NetBSD Foundation + by Dieter Baron and Thomas Klausner. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff --git a/worker/deps/getopt/getopt/README.md b/worker/deps/getopt/getopt/README.md new file mode 100644 index 0000000000..16b855a614 --- /dev/null +++ b/worker/deps/getopt/getopt/README.md @@ -0,0 +1,63 @@ +# wingetopt + +getopt library for Windows compilers + + +This library was created to allow compilation linux-based software on Windows. +http://en.wikipedia.org/wiki/Getopt + +The sources were taken from MinGW-runtime project. + +#### AUTHORS: + +* Todd C. Miller +* The NetBSD Foundation, Inc. + +#### LICENSE + + Copyright (c) 2002 Todd C. Miller + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Sponsored in part by the Defense Advanced Research Projects + Agency (DARPA) and Air Force Research Laboratory, Air Force + Materiel Command, USAF, under agreement number F39502-99-1-0512. + +*** + + Copyright (c) 2000 The NetBSD Foundation, Inc. + All rights reserved. + + This code is derived from software contributed to The NetBSD Foundation + by Dieter Baron and Thomas Klausner. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff --git a/worker/deps/getopt/getopt/src/getopt.c b/worker/deps/getopt/getopt/src/getopt.c new file mode 100644 index 0000000000..0ed0dd2596 --- /dev/null +++ b/worker/deps/getopt/getopt/src/getopt.c @@ -0,0 +1,562 @@ +/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#ifndef __CYGWIN__ +#define __progname __argv[0] +#else +extern char __declspec(dllimport) *__progname; +#endif + +#ifdef __CYGWIN__ +static char EMSG[] = ""; +#else +#define EMSG "" +#endif + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +static void +_vwarnx(const char *fmt,va_list ap) +{ + (void)fprintf(stderr,"%s: ",__progname); + if (fmt != NULL) + (void)vfprintf(stderr,fmt,ap); + (void)fprintf(stderr,"\n"); +} + +static void +warnx(const char *fmt,...) +{ + va_list ap; + va_start(ap,fmt); + _vwarnx(fmt,ap); + va_end(ap); +} + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + current_argv = place; + match = -1; + ambiguous = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +#undef IDENTICAL_INTERPRETATION +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + const char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/worker/deps/getopt/getopt/src/getopt.h b/worker/deps/getopt/getopt/src/getopt.h new file mode 100644 index 0000000000..f3f864bda6 --- /dev/null +++ b/worker/deps/getopt/getopt/src/getopt.h @@ -0,0 +1,105 @@ +#ifndef __GETOPT_H__ +/** + * DISCLAIMER + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the w64 mingw-runtime package. + * + * The w64 mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#define __GETOPT_H__ + +/* All the headers include this file. */ +#include + +#if defined( WINGETOPT_SHARED_LIB ) +# if defined( BUILDING_WINGETOPT_DLL ) +# define WINGETOPT_API __declspec(dllexport) +# else +# define WINGETOPT_API __declspec(dllimport) +# endif +#else +# define WINGETOPT_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +WINGETOPT_API extern int optind; /* index of first non-option in argv */ +WINGETOPT_API extern int optopt; /* single option character, as parsed */ +WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */ + /* (user may set to zero, to suppress) */ + +WINGETOPT_API extern char *optarg; /* pointer to argument of current option */ + +extern int getopt(int nargc, char * const *nargv, const char *options); + +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ +#endif /* !defined(__GETOPT_H__) */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option /* specification for a long form option... */ +{ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; + +enum /* permitted values for its `has_arg' field... */ +{ + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ +}; + +extern int getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +extern int getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +/* + * Previous MinGW implementation had... + */ +#ifndef HAVE_DECL_GETOPT +/* + * ...for the long form API only; keep this for compatibility. + */ +# define HAVE_DECL_GETOPT 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ diff --git a/worker/scripts/get-dep.sh b/worker/scripts/get-dep.sh index f6f7b62401..a0b385b7ab 100755 --- a/worker/scripts/get-dep.sh +++ b/worker/scripts/get-dep.sh @@ -158,6 +158,15 @@ function get_fuzzer_corpora() get_dep "${GIT_REPO}" "${GIT_TAG}" "${DEST}" } +function get_win_getopt() +{ + GIT_REPO="git@github.com:alex85k/wingetopt.git" + GIT_TAG="master" + DEST="deps/getopt/getopt" + + get_dep "${GIT_REPO}" "${GIT_TAG}" "${DEST}" +} + case "${DEP}" in '-h') echo "Usage:" @@ -197,6 +206,9 @@ case "${DEP}" in fuzzer-corpora) get_fuzzer_corpora ;; + get-win-opt) + get_win_getopt + ;; *) echo ">>> [ERROR] unknown dep '${DEP}'" >&2 exit 1 From 793900dd7c57ec13535bd5ea7d5f5c843eb20d25 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sun, 1 Sep 2019 10:45:50 +0800 Subject: [PATCH 19/41] code style --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 04477e4a57..bf6d67a54a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,7 +1,7 @@ +const os = require('os'); const gulp = require('gulp'); const shell = require('gulp-shell'); const clangFormat = require('gulp-clang-format'); -const os = require('os'); const workerFiles = [ From 3585288c4092649cc494bc8515221923496e8807 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sun, 1 Sep 2019 11:17:01 +0800 Subject: [PATCH 20/41] add comment for skipping test case in win32 --- test/test-Worker.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test-Worker.js b/test/test-Worker.js index 08dd9da35e..104e2dc738 100644 --- a/test/test-Worker.js +++ b/test/test-Worker.js @@ -195,6 +195,8 @@ test('Worker emits "died" if worker process died unexpectedly', async () => test('worker process ignores PIPE, HUP, ALRM, USR1 and USR2 signals', async () => { + // windowns doesn't have some signals such as SIGPIPE, SIGALRM, SIGUSR1, SIGUSR2 + // so we just skip this test in windows if (os.platform() === 'win32') return; From 14a38ba357893081042f690ef152d0585f555b51 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sun, 1 Sep 2019 11:44:46 +0800 Subject: [PATCH 21/41] move gulp-clang-format into devDep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4cfd7ec97b..933ca77da7 100644 --- a/package.json +++ b/package.json @@ -45,12 +45,12 @@ "random-number": "^0.0.9", "uuid": "^3.3.2", "gulp": "^4.0.2", - "gulp-clang-format": "^1.0.27", "gulp-shell": "^0.6.5" }, "devDependencies": { "eslint": "^6.1.0", "eslint-plugin-jest": "^22.13.6", + "gulp-clang-format": "^1.0.27", "jest": "^24.8.0", "jest-tobetype": "^1.2.3", "open-cli": "^5.0.0", From cac00ed8906d3643f0aacc15559d361d409d1527 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sun, 1 Sep 2019 23:48:36 +0800 Subject: [PATCH 22/41] unify name --- worker/scripts/get-dep.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worker/scripts/get-dep.sh b/worker/scripts/get-dep.sh index a0b385b7ab..39e652cbf5 100755 --- a/worker/scripts/get-dep.sh +++ b/worker/scripts/get-dep.sh @@ -170,7 +170,7 @@ function get_win_getopt() case "${DEP}" in '-h') echo "Usage:" - echo " ./scripts/$(basename $0) [gyp|json|netstring|libuv|openssl|libsrtp|catch|lcov|clang-fuzzer|fuzzer-corpora]" + echo " ./scripts/$(basename $0) [gyp|json|netstring|libuv|openssl|libsrtp|catch|lcov|clang-fuzzer|fuzzer-corpora|win-getopt]" echo ;; gyp) @@ -206,7 +206,7 @@ case "${DEP}" in fuzzer-corpora) get_fuzzer_corpora ;; - get-win-opt) + win-getopt) get_win_getopt ;; *) From 3dbf56d6b32ab5504d2c2444d73515869f23e1ea Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Mon, 2 Sep 2019 10:07:57 +0800 Subject: [PATCH 23/41] change for lint --- worker/include/RTC/RTCP/FeedbackPsFir.hpp | 2 +- worker/include/common.hpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/worker/include/RTC/RTCP/FeedbackPsFir.hpp b/worker/include/RTC/RTCP/FeedbackPsFir.hpp index 4cc096a299..0602e4c2d5 100644 --- a/worker/include/RTC/RTCP/FeedbackPsFir.hpp +++ b/worker/include/RTC/RTCP/FeedbackPsFir.hpp @@ -28,7 +28,7 @@ namespace RTC uint32_t ssrc; uint8_t sequenceNumber; #ifdef _WIN32 - uint8_t reserved[3]; // Alignment. + uint8_t reserved[3]; // Alignment. #else uint32_t reserved : 24; #endif diff --git a/worker/include/common.hpp b/worker/include/common.hpp index d17a1c9cf1..2a0f7d25f9 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -20,9 +20,9 @@ typedef SSIZE_T ssize_t; #include // sockaddr_in, sockaddr_in6 #include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 #endif -#include // PRIu64, etc -#include // size_t -#include // uint8_t, etc -#include // std::addressof() +#include // PRIu64, etc +#include // size_t +#include // uint8_t, etc +#include // std::addressof() #endif From 4f10db0d1fbd8c8247118f44c488d9678f219b39 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Mon, 2 Sep 2019 10:11:02 +0800 Subject: [PATCH 24/41] use run-script-os instead of gulp --- gulpfile.js | 40 +--------------------------------------- package.json | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index bf6d67a54a..fef1c88f88 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,6 +1,4 @@ -const os = require('os'); const gulp = require('gulp'); -const shell = require('gulp-shell'); const clangFormat = require('gulp-clang-format'); const workerFiles = @@ -38,40 +36,4 @@ gulp.task('format:worker', () => return gulp.src(src, { base: '.' }) .pipe(clangFormat.format('file')) .pipe(gulp.dest('.')); -}); - -gulp.task('win:build', shell.task( - [ - 'echo build for windows', - 'python ./worker/scripts/configure.py --format=msvs', - `MSBuild ./worker/mediasoup-worker.sln /p:Configuration=${process.env.MEDIASOUP_BUILDTYPE === 'Debug' ?'Debug' : 'Release'} -t:mediasoup-worker ` - ], - { - verbose : true - } -)); - -gulp.task('make:build', shell.task( - [ - 'make -C worker' - ], - { - verbose : true - } -)); - -gulp.task('build', gulp.series(os.platform() === 'win32'? 'win:build' : 'make:build')); - -gulp.task('test:win:worker', shell.task( - [ - 'echo not support yet!!! run test in visual studio!!!' - ] -)); - -gulp.task('test:make:worker', shell.task( - [ - 'make test -C worker' - ] -)); - -gulp.task('test:worker', gulp.series(os.platform() === 'win32'? 'test:win:worker' : 'test:make:worker')); +}); \ No newline at end of file diff --git a/package.json b/package.json index 933ca77da7..de57995d8e 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,14 @@ "lint:worker": "gulp lint:worker", "format:worker": "gulp format:worker", "test": "npm run test:node && npm run test:worker", - "test:node": "gulp build && jest", - "test:worker": "gulp test:worker", - "coverage:node": "gulp build && jest --coverage && open-cli coverage/lcov-report/index.html", - "postinstall": "gulp build" + "test:node": "npm run postinstall && jest", + "test:worker": "run-script-os", + "test:worker:win32": "echo test:worker not support yet!!! run test in visual studio!!!", + "test:worker:default": "make test -C worker", + "coverage:node": "npm run postinstall && jest --coverage && open-cli coverage/lcov-report/index.html", + "postinstall": "run-script-os", + "postinstall:win32": "python ./worker/scripts/configure.py --format=msvs && IF %MEDIASOUP_BUILDTYPE% == Release ( MSBuild ./worker/mediasoup-worker.sln /p:Configuration=Release -t:mediasoup-worker ) ELSE ( MSBuild ./worker/mediasoup-worker.sln /p:Configuration=Debug -t:mediasoup-worker )", + "postinstall:default": "make -C worker" }, "jest": { "verbose": true, @@ -43,14 +47,14 @@ "h264-profile-level-id": "^1.0.0", "netstring": "^0.3.0", "random-number": "^0.0.9", - "uuid": "^3.3.2", - "gulp": "^4.0.2", - "gulp-shell": "^0.6.5" + "run-script-os": "git+https://github.com/kawatzaki/run-script-os.git", + "uuid": "^3.3.2" }, "devDependencies": { "eslint": "^6.1.0", "eslint-plugin-jest": "^22.13.6", - "gulp-clang-format": "^1.0.27", + "gulp": "^4.0.2", + "gulp-clang-format": "^1.0.27", "jest": "^24.8.0", "jest-tobetype": "^1.2.3", "open-cli": "^5.0.0", From 174c1dde7da003a5cde69a6ff8181d2d901e4da4 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 4 Sep 2019 00:55:48 +0800 Subject: [PATCH 25/41] use @dr.amaton/run-script-os instead of a git repo --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de57995d8e..ea08505c5f 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "h264-profile-level-id": "^1.0.0", "netstring": "^0.3.0", "random-number": "^0.0.9", - "run-script-os": "git+https://github.com/kawatzaki/run-script-os.git", + "@dr.amaton/run-script-os": "^1.1.2", "uuid": "^3.3.2" }, "devDependencies": { From 7b2053498b1ea681f188d79613072c844428e51f Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 6 Sep 2019 01:41:32 +0800 Subject: [PATCH 26/41] win tasks --- package.json | 4 +- worker/win-tasks.js | 199 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 worker/win-tasks.js diff --git a/package.json b/package.json index ea08505c5f..0c9f39e42e 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,11 @@ "test": "npm run test:node && npm run test:worker", "test:node": "npm run postinstall && jest", "test:worker": "run-script-os", - "test:worker:win32": "echo test:worker not support yet!!! run test in visual studio!!!", + "test:worker:win32": "\"\"%NODE%\"\" ./worker/win-tasks.js test", "test:worker:default": "make test -C worker", "coverage:node": "npm run postinstall && jest --coverage && open-cli coverage/lcov-report/index.html", "postinstall": "run-script-os", - "postinstall:win32": "python ./worker/scripts/configure.py --format=msvs && IF %MEDIASOUP_BUILDTYPE% == Release ( MSBuild ./worker/mediasoup-worker.sln /p:Configuration=Release -t:mediasoup-worker ) ELSE ( MSBuild ./worker/mediasoup-worker.sln /p:Configuration=Debug -t:mediasoup-worker )", + "postinstall:win32": "\"\"%NODE%\"\" ./worker/win-tasks.js make", "postinstall:default": "make -C worker" }, "jest": { diff --git a/worker/win-tasks.js b/worker/win-tasks.js new file mode 100644 index 0000000000..b6234c5536 --- /dev/null +++ b/worker/win-tasks.js @@ -0,0 +1,199 @@ +'use strict'; + +const exec = require('child_process').exec; +const path = require('path'); + +const PYTHON = process.env.PYTHON || 'python'; +const GULP = path.join(__dirname, '..', 'node_modules', '.bin', 'gulp'); +const MSBUILD = process.env.MSBUILD || 'MSBuild'; +const MEDIASOUP_BUILDTYPE = process.env.MEDIASOUP_BUILDTYPE || 'Release'; +const DEL = process.env.DEL || 'del'; +const RD = process.env.RM || 'rd'; + +run(); + +function run() { + const usage = 'usage:[-h/help/make/test/fuzzer/lint/format/bear/tidy/clean/clean-all/docker-build/docker-run]'; + if (process.argv.length < 3) { + console.error(usage); + return; + } + + var command = process.argv[2]; + switch (command) { + case '-h': + case 'help': + console.log(usage); + break; + case 'make': { + if (!process.env.MEDIASOUP_WORKER_BIN) { + var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker`; + var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; + execute(`${generScript} && ${buildScript}`) + } + break; + } + case 'test': { + if (!process.env.MEDIASOUP_WORKER_BIN) { + var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker-test`; + var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; + // TODO(tonywu) : find a alternative tool to replace LCOV + execute(`${generScript} && ${buildScript}`) + } + break; + } + case 'fuzzer': { + var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker-fuzzer`; + var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; + execute(`${generScript} && ${buildScript}`) + break; + } + case 'lint': { + execute(`${GULP} lint:worker`); + break; + } + case 'format': { + execute(`${GULP} format:worker`); + break; + } + case 'bear': { + console.warn('not support yet.'); + break; + } + case 'tidy': { + console.warn('not support yet.'); + break; + } + case 'clean': { + execute(`${DEL} /s /q .\\worker\\Debug\\`); + execute(`${DEL} /s /q .\\worker\\Release\\`); + + execute(`${DEL} /s /q .\\worker\\out\\Debug`); + execute(`${DEL} /s /q .\\worker\\out\\Release`); + + execute(`${DEL} /s /q .\\worker\\deps\\getopt\\Debug`); + execute(`${DEL} /s /q .\\worker\\deps\\getopt\\Release`); + + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\Debug`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\Release`); + + execute(`${DEL} /s /q .\\worker\\deps\\libuv\\Debug`); + execute(`${DEL} /s /q .\\worker\\deps\\libuv\\Release`); + + execute(`${DEL} /s /q .\\worker\\deps\\netstring\\Debug`); + execute(`${DEL} /s /q .\\worker\\deps\\netstring\\Release`); + + execute(`${DEL} /s /q .\\worker\\deps\\openssl\\Debug`); + execute(`${DEL} /s /q .\\worker\\deps\\openssl\\Release`); + + execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\Debug`); + execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\Release`); + break; + } + case 'clean-all': { + execute(`${RD} /s /q .\\worker\\out\\`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker.sln`); + + execute(`${RD} /s /q .\\worker\\Debug`); + execute(`${RD} /s /q .\\worker\\Release\\`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker.vcxproj`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker.vcxproj.user`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker-test.vcxproj`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker-test.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker-test.vcxproj.user`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker-fuzzer.vcxproj`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker-fuzzer.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\mediasoup-worker-fuzzer.vcxproj.user`); + + execute(`${RD} /s /q .\\worker\\deps\\getopt\\Debug`); + execute(`${RD} /s /q .\\worker\\deps\\getopt\\Release`); + execute(`${DEL} /s /q .\\worker\\deps\\getopt\\*.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\getopt\\*.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\getopt\\*.vcxproj.user`); + + execute(`${RD} /s /q .\\worker\\deps\\libsrtp\\Debug`); + execute(`${RD} /s /q .\\worker\\deps\\libsrtp\\Release`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.sln`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.vcxproj.user`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rdbx_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rdbx_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\replay_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\replay_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\roc_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\roc_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rtpw.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rtpw.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_runtest.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_runtest.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_aes_calc.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_aes_calc.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_cipher_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_cipher_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_datatypes_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_datatypes_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_env.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_env.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_kernel_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_kernel_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen_soak.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen_soak.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_sha1_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_sha1_driver.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_stat_driver.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_stat_driver.vcxproj.filters`); + + execute(`${RD} /s /q .\\worker\\deps\\libuv\\Debug`); + execute(`${RD} /s /q .\\worker\\deps\\libuv\\Release`); + execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.sln`); + execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.vcxproj.user`); + + execute(`${RD} /s /q .\\worker\\deps\\netstring\\Debug`); + execute(`${RD} /s /q .\\worker\\deps\\netstring\\Release`); + execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.sln`); + execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.vcxproj.user`); + + execute(`${RD} /s /q .\\worker\\deps\\openssl\\Debug`); + execute(`${RD} /s /q .\\worker\\deps\\openssl\\Release`); + execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.sln`); + execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.vcxproj.user`); + + execute(`${RD} /s /q .\\worker\\deps\\usrsctp\\Debug`); + execute(`${RD} /s /q .\\worker\\deps\\usrsctp\\Release`); + execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.sln`); + execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.vcxproj`); + execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.vcxproj.filters`); + execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.vcxproj.user`); + break; + } + case 'docker-build': { + console.warn('not support yet.'); + break; + } + case 'docker-run': { + console.warn('not support yet.'); + break; + } + default: { + console.warn('unknown command'); + } + } +} + +function execute(command) { + var childProcess = exec(command); + childProcess.stdout.pipe(process.stdout); + childProcess.stderr.pipe(process.stderr); +}; From e70535c1c862b4823da5a08e1b95c88fe5e41390 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sat, 7 Sep 2019 14:45:31 +0800 Subject: [PATCH 27/41] remove useless tasks --- package.json | 8 ++- worker/win-tasks.js | 142 +------------------------------------------- 2 files changed, 7 insertions(+), 143 deletions(-) diff --git a/package.json b/package.json index 0c9f39e42e..8c4239ea59 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,12 @@ "scripts": { "lint": "npm run lint:node && npm run lint:worker", "lint:node": "eslint -c .eslintrc.js gulpfile.js lib test", - "lint:worker": "gulp lint:worker", - "format:worker": "gulp format:worker", + "lint:worker": "run-script-os", + "lint:worker:win32": "\"\"%NODE%\"\" ./worker/win-tasks.js lint", + "lint:worker:default": "make lint -C worker", + "format:worker": "run-script-os", + "format:worker:win32": "\"\"%NODE%\"\" ./worker/win-tasks.js format", + "format:worker:default": "make format -C worker", "test": "npm run test:node && npm run test:worker", "test:node": "npm run postinstall && jest", "test:worker": "run-script-os", diff --git a/worker/win-tasks.js b/worker/win-tasks.js index b6234c5536..581a9f2e6b 100644 --- a/worker/win-tasks.js +++ b/worker/win-tasks.js @@ -1,5 +1,3 @@ -'use strict'; - const exec = require('child_process').exec; const path = require('path'); @@ -7,13 +5,11 @@ const PYTHON = process.env.PYTHON || 'python'; const GULP = path.join(__dirname, '..', 'node_modules', '.bin', 'gulp'); const MSBUILD = process.env.MSBUILD || 'MSBuild'; const MEDIASOUP_BUILDTYPE = process.env.MEDIASOUP_BUILDTYPE || 'Release'; -const DEL = process.env.DEL || 'del'; -const RD = process.env.RM || 'rd'; run(); function run() { - const usage = 'usage:[-h/help/make/test/fuzzer/lint/format/bear/tidy/clean/clean-all/docker-build/docker-run]'; + const usage = 'usage:[-h/help/make/test/lint/format]'; if (process.argv.length < 3) { console.error(usage); return; @@ -42,12 +38,6 @@ function run() { } break; } - case 'fuzzer': { - var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker-fuzzer`; - var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; - execute(`${generScript} && ${buildScript}`) - break; - } case 'lint': { execute(`${GULP} lint:worker`); break; @@ -56,136 +46,6 @@ function run() { execute(`${GULP} format:worker`); break; } - case 'bear': { - console.warn('not support yet.'); - break; - } - case 'tidy': { - console.warn('not support yet.'); - break; - } - case 'clean': { - execute(`${DEL} /s /q .\\worker\\Debug\\`); - execute(`${DEL} /s /q .\\worker\\Release\\`); - - execute(`${DEL} /s /q .\\worker\\out\\Debug`); - execute(`${DEL} /s /q .\\worker\\out\\Release`); - - execute(`${DEL} /s /q .\\worker\\deps\\getopt\\Debug`); - execute(`${DEL} /s /q .\\worker\\deps\\getopt\\Release`); - - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\Debug`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\Release`); - - execute(`${DEL} /s /q .\\worker\\deps\\libuv\\Debug`); - execute(`${DEL} /s /q .\\worker\\deps\\libuv\\Release`); - - execute(`${DEL} /s /q .\\worker\\deps\\netstring\\Debug`); - execute(`${DEL} /s /q .\\worker\\deps\\netstring\\Release`); - - execute(`${DEL} /s /q .\\worker\\deps\\openssl\\Debug`); - execute(`${DEL} /s /q .\\worker\\deps\\openssl\\Release`); - - execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\Debug`); - execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\Release`); - break; - } - case 'clean-all': { - execute(`${RD} /s /q .\\worker\\out\\`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker.sln`); - - execute(`${RD} /s /q .\\worker\\Debug`); - execute(`${RD} /s /q .\\worker\\Release\\`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker.vcxproj`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker.vcxproj.user`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker-test.vcxproj`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker-test.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker-test.vcxproj.user`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker-fuzzer.vcxproj`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker-fuzzer.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\mediasoup-worker-fuzzer.vcxproj.user`); - - execute(`${RD} /s /q .\\worker\\deps\\getopt\\Debug`); - execute(`${RD} /s /q .\\worker\\deps\\getopt\\Release`); - execute(`${DEL} /s /q .\\worker\\deps\\getopt\\*.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\getopt\\*.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\getopt\\*.vcxproj.user`); - - execute(`${RD} /s /q .\\worker\\deps\\libsrtp\\Debug`); - execute(`${RD} /s /q .\\worker\\deps\\libsrtp\\Release`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.sln`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\libsrtp.vcxproj.user`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rdbx_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rdbx_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\replay_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\replay_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\roc_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\roc_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rtpw.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\rtpw.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_runtest.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_runtest.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_aes_calc.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_aes_calc.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_cipher_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_cipher_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_datatypes_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_datatypes_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_env.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_env.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_kernel_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_kernel_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen_soak.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_rand_gen_soak.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_sha1_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_sha1_driver.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_stat_driver.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libsrtp\\srtp_test_stat_driver.vcxproj.filters`); - - execute(`${RD} /s /q .\\worker\\deps\\libuv\\Debug`); - execute(`${RD} /s /q .\\worker\\deps\\libuv\\Release`); - execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.sln`); - execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\libuv\\*.vcxproj.user`); - - execute(`${RD} /s /q .\\worker\\deps\\netstring\\Debug`); - execute(`${RD} /s /q .\\worker\\deps\\netstring\\Release`); - execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.sln`); - execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\netstring\\*.vcxproj.user`); - - execute(`${RD} /s /q .\\worker\\deps\\openssl\\Debug`); - execute(`${RD} /s /q .\\worker\\deps\\openssl\\Release`); - execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.sln`); - execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\openssl\\*.vcxproj.user`); - - execute(`${RD} /s /q .\\worker\\deps\\usrsctp\\Debug`); - execute(`${RD} /s /q .\\worker\\deps\\usrsctp\\Release`); - execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.sln`); - execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.vcxproj`); - execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.vcxproj.filters`); - execute(`${DEL} /s /q .\\worker\\deps\\usrsctp\\*.vcxproj.user`); - break; - } - case 'docker-build': { - console.warn('not support yet.'); - break; - } - case 'docker-run': { - console.warn('not support yet.'); - break; - } default: { console.warn('unknown command'); } From a4bed7d336e0c0f21380d29352fe4801b62297fb Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sat, 7 Sep 2019 15:04:19 +0800 Subject: [PATCH 28/41] run mediasoup-worker-test --- worker/win-tasks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worker/win-tasks.js b/worker/win-tasks.js index 581a9f2e6b..a96e39985f 100644 --- a/worker/win-tasks.js +++ b/worker/win-tasks.js @@ -5,7 +5,7 @@ const PYTHON = process.env.PYTHON || 'python'; const GULP = path.join(__dirname, '..', 'node_modules', '.bin', 'gulp'); const MSBUILD = process.env.MSBUILD || 'MSBuild'; const MEDIASOUP_BUILDTYPE = process.env.MEDIASOUP_BUILDTYPE || 'Release'; - +const MEDIASOUP_TEST_TAGS = process.env.MEDIASOUP_TEST_TAGS || ''; run(); function run() { @@ -33,8 +33,8 @@ function run() { if (!process.env.MEDIASOUP_WORKER_BIN) { var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker-test`; var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; - // TODO(tonywu) : find a alternative tool to replace LCOV - execute(`${generScript} && ${buildScript}`) + var testScript = `cd worker && .\\out\\${MEDIASOUP_BUILDTYPE}\\mediasoup-worker-test.exe --invisibles --use-colour=yes ${MEDIASOUP_TEST_TAGS}` + execute(`${generScript} && ${buildScript} && ${testScript}`) } break; } From e566abed90e471e40a4fd61edafc3a5ed0e65d53 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sat, 7 Sep 2019 15:28:22 +0800 Subject: [PATCH 29/41] add win-tasks.js to lint --- package.json | 2 +- worker/win-tasks.js | 116 ++++++++++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index 8c4239ea59..8a64a8d78a 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ }, "scripts": { "lint": "npm run lint:node && npm run lint:worker", - "lint:node": "eslint -c .eslintrc.js gulpfile.js lib test", + "lint:node": "eslint -c .eslintrc.js gulpfile.js lib test worker/win-tasks.js", "lint:worker": "run-script-os", "lint:worker:win32": "\"\"%NODE%\"\" ./worker/win-tasks.js lint", "lint:worker:default": "make lint -C worker", diff --git a/worker/win-tasks.js b/worker/win-tasks.js index a96e39985f..d09e02f92d 100644 --- a/worker/win-tasks.js +++ b/worker/win-tasks.js @@ -6,54 +6,76 @@ const GULP = path.join(__dirname, '..', 'node_modules', '.bin', 'gulp'); const MSBUILD = process.env.MSBUILD || 'MSBuild'; const MEDIASOUP_BUILDTYPE = process.env.MEDIASOUP_BUILDTYPE || 'Release'; const MEDIASOUP_TEST_TAGS = process.env.MEDIASOUP_TEST_TAGS || ''; + +const usage = 'usage:[-h/help/make/test/lint/format]'; + run(); -function run() { - const usage = 'usage:[-h/help/make/test/lint/format]'; - if (process.argv.length < 3) { - console.error(usage); - return; - } - - var command = process.argv[2]; - switch (command) { - case '-h': - case 'help': - console.log(usage); - break; - case 'make': { - if (!process.env.MEDIASOUP_WORKER_BIN) { - var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker`; - var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; - execute(`${generScript} && ${buildScript}`) - } - break; - } - case 'test': { - if (!process.env.MEDIASOUP_WORKER_BIN) { - var generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker-test`; - var buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; - var testScript = `cd worker && .\\out\\${MEDIASOUP_BUILDTYPE}\\mediasoup-worker-test.exe --invisibles --use-colour=yes ${MEDIASOUP_TEST_TAGS}` - execute(`${generScript} && ${buildScript} && ${testScript}`) - } - break; - } - case 'lint': { - execute(`${GULP} lint:worker`); - break; - } - case 'format': { - execute(`${GULP} format:worker`); - break; - } - default: { - console.warn('unknown command'); - } - } +/* eslint-disable no-console */ +function run() +{ + if (process.argv.length < 3) + { + console.error(usage); + + return; + } + + const command = process.argv[2]; + + switch (command) + { + case '-h': + case 'help': + { + console.log(usage); + break; + } + case 'make': + { + if (!process.env.MEDIASOUP_WORKER_BIN) + { + const generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker`; + const buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; + + execute(`${generScript} && ${buildScript}`); + } + break; + } + case 'test': + { + if (!process.env.MEDIASOUP_WORKER_BIN) + { + const generScript = `${PYTHON} ./worker/scripts/configure.py --format=msvs -R mediasoup-worker-test`; + const buildScript = `${MSBUILD} ./worker/mediasoup-worker.sln /p:Configuration=${MEDIASOUP_BUILDTYPE}`; + const testScript = `cd worker && .\\out\\${MEDIASOUP_BUILDTYPE}\\mediasoup-worker-test.exe --invisibles --use-colour=yes ${MEDIASOUP_TEST_TAGS}`; + + execute(`${generScript} && ${buildScript} && ${testScript}`); + } + break; + } + case 'lint': + { + execute(`${GULP} lint:worker`); + break; + } + case 'format': + { + execute(`${GULP} format:worker`); + break; + } + default: + { + console.warn('unknown command'); + } + } } +/* eslint-enable no-console */ -function execute(command) { - var childProcess = exec(command); - childProcess.stdout.pipe(process.stdout); - childProcess.stderr.pipe(process.stderr); -}; +function execute(command) +{ + const childProcess = exec(command); + + childProcess.stdout.pipe(process.stdout); + childProcess.stderr.pipe(process.stderr); +} From cda5e7e380ede1927dabeca7d023c1637f51f007 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 11 Sep 2019 11:23:29 +0800 Subject: [PATCH 30/41] code style --- .eslintrc.js | 3 +-- .gitignore | 4 ++-- gulpfile.js | 2 +- test/test-Worker.js | 4 ++-- worker/mediasoup-worker.gyp | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d390f63d0c..c2d0f1c8d8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -172,7 +172,6 @@ module.exports = 'spaced-comment': [ 2, 'always' ], 'strict': 2, 'valid-typeof': 2, - 'yoda': 2, - 'linebreak-style': 0 + 'yoda': 2 } }; diff --git a/.gitignore b/.gitignore index 761ee961c9..6e7c047da4 100644 --- a/.gitignore +++ b/.gitignore @@ -30,9 +30,9 @@ # python win generated Stuff. /worker/scripts/configure.pyc -# vistual studio generated Stuff. +# Vistual Studio generated Stuff. /worker/**/Debug/ /worker/**/Release/ -# VS stuff. +# Vistual Studio Code stuff. /worker/.vs/ diff --git a/gulpfile.js b/gulpfile.js index fef1c88f88..bad255eab7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -36,4 +36,4 @@ gulp.task('format:worker', () => return gulp.src(src, { base: '.' }) .pipe(clangFormat.format('file')) .pipe(gulp.dest('.')); -}); \ No newline at end of file +}); diff --git a/test/test-Worker.js b/test/test-Worker.js index 104e2dc738..7569a4d81c 100644 --- a/test/test-Worker.js +++ b/test/test-Worker.js @@ -195,8 +195,8 @@ test('Worker emits "died" if worker process died unexpectedly', async () => test('worker process ignores PIPE, HUP, ALRM, USR1 and USR2 signals', async () => { - // windowns doesn't have some signals such as SIGPIPE, SIGALRM, SIGUSR1, SIGUSR2 - // so we just skip this test in windows + // Windows doesn't have some signals such as SIGPIPE, SIGALRM, SIGUSR1, SIGUSR2 + // so we just skip this test in Windows. if (os.platform() === 'win32') return; diff --git a/worker/mediasoup-worker.gyp b/worker/mediasoup-worker.gyp index ee83584cd8..c2f0612810 100644 --- a/worker/mediasoup-worker.gyp +++ b/worker/mediasoup-worker.gyp @@ -274,7 +274,7 @@ [ 'OS == "win"', { 'dependencies': [ 'deps/getopt/getopt.gyp:getopt' ], - # handle multi files with same name. + # Handle multi files with same name. # https://stackoverflow.com/a/22936230/2085408 # https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vcprojectengine.vcclcompilertool.objectfile?view=visualstudiosdk-2017#Microsoft_VisualStudio_VCProjectEngine_VCCLCompilerTool_ObjectFile 'msvs_settings': { From 6885c4488abe1268a78401268298a5f18b6e313b Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 11 Sep 2019 11:31:43 +0800 Subject: [PATCH 31/41] code style and readability --- worker/src/Channel/Request.cpp | 16 +++++----------- worker/src/Worker.cpp | 2 +- worker/src/main.cpp | 6 +++--- worker/win-tasks.js | 1 + 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/worker/src/Channel/Request.cpp b/worker/src/Channel/Request.cpp index 1cbb3ce49b..0f1c27a301 100644 --- a/worker/src/Channel/Request.cpp +++ b/worker/src/Channel/Request.cpp @@ -57,11 +57,9 @@ namespace Channel }; // clang-format on - /* Class variables. */ - Channel::UnixStreamSocket* Request::channel{ nullptr }; - /* Static methods. */ + /* Class methods. */ void Request::ClassInit(Channel::UnixStreamSocket* channel) { @@ -125,8 +123,7 @@ namespace Channel { MS_TRACE(); - MS_ASSERT(Request::channel != nullptr, "channel unset"); - + MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -143,8 +140,7 @@ namespace Channel { MS_TRACE(); - MS_ASSERT(Request::channel != nullptr, "channel unset"); - + MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -164,8 +160,7 @@ namespace Channel { MS_TRACE(); - MS_ASSERT(Request::channel != nullptr, "channel unset"); - + MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -185,8 +180,7 @@ namespace Channel { MS_TRACE(); - MS_ASSERT(Request::channel != nullptr, "channel unset"); - + MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; diff --git a/worker/src/Worker.cpp b/worker/src/Worker.cpp index b98fc4a432..0d8307f1e1 100644 --- a/worker/src/Worker.cpp +++ b/worker/src/Worker.cpp @@ -124,7 +124,7 @@ inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* socket, Channel: MS_TRACE(); MS_ASSERT( - socket != &this->channel->producerSocket, "Producer Socket should not used as request channel"); + socket != &(this->channel->producerSocket), "Producer Socket should not be used for receiving requests"); MS_DEBUG_DEV( "Channel request received [method:%s, id:%" PRIu32 "]", request->method.c_str(), request->id); diff --git a/worker/src/main.cpp b/worker/src/main.cpp index 19b1b96124..9abe767b2a 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -62,7 +62,7 @@ int main(int argc, char* argv[]) } // Initialize the Logger. - Logger::ClassInit(&channel->producerSocket); + Logger::ClassInit(&(channel->producerSocket)); try { @@ -112,8 +112,8 @@ int main(int argc, char* argv[]) Utils::Crypto::ClassInit(); RTC::DtlsTransport::ClassInit(); RTC::SrtpSession::ClassInit(); - Channel::Notifier::ClassInit(&channel->producerSocket); - Channel::Request::ClassInit(&channel->producerSocket); + Channel::Notifier::ClassInit(&(channel->producerSocket)); + Channel::Request::ClassInit(&(channel->producerSocket)); // Ignore some signals. IgnoreSignals(); diff --git a/worker/win-tasks.js b/worker/win-tasks.js index d09e02f92d..e71057b2f0 100644 --- a/worker/win-tasks.js +++ b/worker/win-tasks.js @@ -79,3 +79,4 @@ function execute(command) childProcess.stdout.pipe(process.stdout); childProcess.stderr.pipe(process.stderr); } + From b6775abb30dea7c1b972a98e06bf8a8d6a0f7dab Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 11 Sep 2019 11:36:23 +0800 Subject: [PATCH 32/41] code style --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6e7c047da4..d786e09747 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,7 @@ # Mac Stuff. .DS_Store -# python win generated Stuff. +# Python generated stuff in Windows. /worker/scripts/configure.pyc # Vistual Studio generated Stuff. From faa375fbbbfb6a65992886d14674d0aca527dcca Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 11 Sep 2019 12:28:55 +0800 Subject: [PATCH 33/41] code style --- worker/src/Worker.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worker/src/Worker.cpp b/worker/src/Worker.cpp index 0d8307f1e1..ee4bf06aff 100644 --- a/worker/src/Worker.cpp +++ b/worker/src/Worker.cpp @@ -124,7 +124,8 @@ inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* socket, Channel: MS_TRACE(); MS_ASSERT( - socket != &(this->channel->producerSocket), "Producer Socket should not be used for receiving requests"); + socket != &(this->channel->producerSocket), + "Producer Socket should not be used for receiving requests"); MS_DEBUG_DEV( "Channel request received [method:%s, id:%" PRIu32 "]", request->method.c_str(), request->id); From 6578c6b06dfb02198257f7765e952ca785c3f016 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 11 Sep 2019 21:37:17 +0800 Subject: [PATCH 34/41] remove duplicated LF --- worker/win-tasks.js | 1 - 1 file changed, 1 deletion(-) diff --git a/worker/win-tasks.js b/worker/win-tasks.js index e71057b2f0..d09e02f92d 100644 --- a/worker/win-tasks.js +++ b/worker/win-tasks.js @@ -79,4 +79,3 @@ function execute(command) childProcess.stdout.pipe(process.stdout); childProcess.stderr.pipe(process.stderr); } - From 6fbcc2aff91dc42ad8044935fe308a8d21a3990a Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Wed, 11 Sep 2019 21:49:22 +0800 Subject: [PATCH 35/41] wrap consumer socket and producer socket --- worker/include/Channel/Request.hpp | 11 +-- worker/include/Channel/UnixStreamSocket.hpp | 58 +++++++---- worker/include/Worker.hpp | 4 +- worker/src/Channel/Request.cpp | 25 +---- worker/src/Channel/UnixStreamSocket.cpp | 104 ++++++++++++-------- worker/src/Worker.cpp | 11 +-- worker/src/main.cpp | 9 +- 7 files changed, 122 insertions(+), 100 deletions(-) diff --git a/worker/include/Channel/Request.hpp b/worker/include/Channel/Request.hpp index 096bb25254..ed02f96cbc 100644 --- a/worker/include/Channel/Request.hpp +++ b/worker/include/Channel/Request.hpp @@ -67,7 +67,7 @@ namespace Channel static std::unordered_map string2MethodId; public: - explicit Request(json& jsonRequest); + Request(Channel::UnixStreamSocket* channel, json& jsonRequest); virtual ~Request(); void Accept(); @@ -76,6 +76,8 @@ namespace Channel void TypeError(const char* reason = nullptr); public: + // Passed by argument. + Channel::UnixStreamSocket* channel{ nullptr }; uint32_t id{ 0u }; std::string method; MethodId methodId; @@ -83,13 +85,6 @@ namespace Channel json data; // Others. bool replied{ false }; - - public: - static void ClassInit(Channel::UnixStreamSocket* channel); - - public: - // Passed by argument. - static Channel::UnixStreamSocket* channel; }; } // namespace Channel diff --git a/worker/include/Channel/UnixStreamSocket.hpp b/worker/include/Channel/UnixStreamSocket.hpp index d30af13833..5df938c1a5 100644 --- a/worker/include/Channel/UnixStreamSocket.hpp +++ b/worker/include/Channel/UnixStreamSocket.hpp @@ -8,25 +8,18 @@ namespace Channel { - class UnixStreamSocket : public ::UnixStreamSocket + class ConsumerSocket : public ::UnixStreamSocket { public: class Listener { public: - virtual void OnChannelRequest(Channel::UnixStreamSocket* channel, Channel::Request* request) = 0; - virtual void OnChannelRemotelyClosed(Channel::UnixStreamSocket* channel) = 0; + virtual void OnSocketRequest(::UnixStreamSocket* socket, json& jsonRequest) = 0; + virtual void OnSocketRemotelyClosed(::UnixStreamSocket* socket) = 0; }; public: - explicit UnixStreamSocket(int fd, ::UnixStreamSocket::Role role); - - public: - void SetListener(Listener* listener); - void Send(json& jsonMessage); - void SendLog(char* nsPayload, size_t nsPayloadLen); - void SendBinary(const uint8_t* nsPayload, size_t nsPayloadLen); - + ConsumerSocket(int fd, size_t bufferSize, Listener* listener); /* Pure virtual methods inherited from ::UnixStreamSocket. */ public: void UserOnUnixStreamRead() override; @@ -39,19 +32,50 @@ namespace Channel size_t msgStart{ 0 }; // Where the latest message starts. }; - class ChannelWrapper + class ProducerSocket : public ::UnixStreamSocket { public: - ChannelWrapper(int consumerFd, int producerFd) - : consumerSocket(consumerFd, ::UnixStreamSocket::Role::CONSUMER), - producerSocket(producerFd, ::UnixStreamSocket::Role::PRODUCER) + ProducerSocket(int fd, size_t bufferSize); + /* Pure virtual methods inherited from ::UnixStreamSocket. */ + public: + void UserOnUnixStreamRead() override { } + void UserOnUnixStreamSocketClosed(bool isClosedByPeer) override + { + } + }; + class UnixStreamSocket : public ConsumerSocket::Listener + { public: + class Listener + { + public: + virtual void OnChannelRequest(Channel::UnixStreamSocket* channel, Channel::Request* request) = 0; + virtual void OnChannelRemotelyClosed(Channel::UnixStreamSocket* channel) = 0; + }; + + public: + explicit UnixStreamSocket(int consumerFd, int producerFd); + + public: + void SetListener(Listener* listener); + void Send(json& jsonMessage); + void SendLog(char* nsPayload, size_t nsPayloadLen); + void SendBinary(const uint8_t* nsPayload, size_t nsPayloadLen); + + /* Pure virtual methods inherited from ::ConsumerSocket::Listener. */ + public: + void OnSocketRequest(::UnixStreamSocket* socket, json& jsonRequest) override; + void OnSocketRemotelyClosed(::UnixStreamSocket* socket) override; + + private: // Passed by argument. - UnixStreamSocket consumerSocket; - UnixStreamSocket producerSocket; + Listener* listener{ nullptr }; + + ConsumerSocket consumerSocket; + ProducerSocket producerSocket; }; } // namespace Channel diff --git a/worker/include/Worker.hpp b/worker/include/Worker.hpp index 970401fe09..d1cd9f307e 100644 --- a/worker/include/Worker.hpp +++ b/worker/include/Worker.hpp @@ -15,7 +15,7 @@ using json = nlohmann::json; class Worker : public Channel::UnixStreamSocket::Listener, public SignalsHandler::Listener { public: - explicit Worker(Channel::ChannelWrapper* channel); + explicit Worker(Channel::UnixStreamSocket* channel); ~Worker(); private: @@ -35,7 +35,7 @@ class Worker : public Channel::UnixStreamSocket::Listener, public SignalsHandler private: // Passed by argument. - Channel::ChannelWrapper* channel{ nullptr }; + Channel::UnixStreamSocket* channel{ nullptr }; // Allocated by this. SignalsHandler* signalsHandler{ nullptr }; // Others. diff --git a/worker/src/Channel/Request.cpp b/worker/src/Channel/Request.cpp index 0f1c27a301..8e34992a9f 100644 --- a/worker/src/Channel/Request.cpp +++ b/worker/src/Channel/Request.cpp @@ -57,20 +57,9 @@ namespace Channel }; // clang-format on - Channel::UnixStreamSocket* Request::channel{ nullptr }; - - /* Class methods. */ - - void Request::ClassInit(Channel::UnixStreamSocket* channel) - { - MS_TRACE(); - - Request::channel = channel; - } - /* Instance methods. */ - Request::Request(json& jsonRequest) + Request::Request(Channel::UnixStreamSocket* channel, json& jsonRequest) : channel(channel) { MS_TRACE(); @@ -123,7 +112,6 @@ namespace Channel { MS_TRACE(); - MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -133,14 +121,13 @@ namespace Channel jsonResponse["id"] = this->id; jsonResponse["accepted"] = true; - Request::channel->Send(jsonResponse); + this->channel->Send(jsonResponse); } void Request::Accept(json& data) { MS_TRACE(); - MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -153,14 +140,13 @@ namespace Channel if (data.is_structured()) jsonResponse["data"] = data; - Request::channel->Send(jsonResponse); + this->channel->Send(jsonResponse); } void Request::Error(const char* reason) { MS_TRACE(); - MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -173,14 +159,13 @@ namespace Channel if (reason != nullptr) jsonResponse["reason"] = reason; - Request::channel->Send(jsonResponse); + this->channel->Send(jsonResponse); } void Request::TypeError(const char* reason) { MS_TRACE(); - MS_ASSERT(Request::channel, "channel unset"); MS_ASSERT(!this->replied, "request already replied"); this->replied = true; @@ -193,6 +178,6 @@ namespace Channel if (reason != nullptr) jsonResponse["reason"] = reason; - Request::channel->Send(jsonResponse); + this->channel->Send(jsonResponse); } } // namespace Channel diff --git a/worker/src/Channel/UnixStreamSocket.cpp b/worker/src/Channel/UnixStreamSocket.cpp index 2825afe1fb..16ff043583 100644 --- a/worker/src/Channel/UnixStreamSocket.cpp +++ b/worker/src/Channel/UnixStreamSocket.cpp @@ -21,9 +21,8 @@ namespace Channel static uint8_t WriteBuffer[NsMessageMaxLen]; /* Instance methods. */ - - UnixStreamSocket::UnixStreamSocket(int fd, ::UnixStreamSocket::Role role) - : ::UnixStreamSocket::UnixStreamSocket(fd, NsMessageMaxLen, role) + UnixStreamSocket::UnixStreamSocket(int consumerFd, int producerFd) + : consumerSocket(consumerFd, NsMessageMaxLen, this), producerSocket(producerFd, NsMessageMaxLen) { MS_TRACE_STD(); } @@ -37,7 +36,7 @@ namespace Channel void UnixStreamSocket::Send(json& jsonMessage) { - if (IsClosed()) + if (producerSocket.IsClosed()) return; std::string nsPayload = jsonMessage.dump(); @@ -69,12 +68,12 @@ namespace Channel nsLen = nsNumLen + nsPayloadLen + 2; - Write(WriteBuffer, nsLen); + producerSocket.Write(WriteBuffer, nsLen); } void UnixStreamSocket::SendLog(char* nsPayload, size_t nsPayloadLen) { - if (IsClosed()) + if (producerSocket.IsClosed()) return; // MS_TRACE_STD(); @@ -106,12 +105,12 @@ namespace Channel nsLen = nsNumLen + nsPayloadLen + 2; - Write(WriteBuffer, nsLen); + producerSocket.Write(WriteBuffer, nsLen); } void UnixStreamSocket::SendBinary(const uint8_t* nsPayload, size_t nsPayloadLen) { - if (IsClosed()) + if (producerSocket.IsClosed()) return; size_t nsNumLen; @@ -141,10 +140,55 @@ namespace Channel nsLen = nsNumLen + nsPayloadLen + 2; - Write(WriteBuffer, nsLen); + producerSocket.Write(WriteBuffer, nsLen); + } + + void UnixStreamSocket::OnSocketRequest(::UnixStreamSocket* socket, json& jsonRequest) + { + Channel::Request* request{ nullptr }; + + try + { + request = new Channel::Request(this, jsonRequest); + } + catch (const MediaSoupError& error) + { + MS_ERROR_STD("discarding wrong Channel request"); + } + + if (request != nullptr) + { + // Notify the listener. + try + { + this->listener->OnChannelRequest(this, request); + } + catch (const MediaSoupTypeError& error) + { + request->TypeError(error.what()); + } + catch (const MediaSoupError& error) + { + request->Error(error.what()); + } + + // Delete the Request. + delete request; + } + } + + void UnixStreamSocket::OnSocketRemotelyClosed(::UnixStreamSocket* socket) + { + this->listener->OnChannelRemotelyClosed(this); } - void UnixStreamSocket::UserOnUnixStreamRead() + ConsumerSocket::ConsumerSocket(int fd, size_t bufferSize, Listener* listener) + : ::UnixStreamSocket(fd, bufferSize, ::UnixStreamSocket::Role::CONSUMER), listener(listener) + { + MS_TRACE_STD(); + } + + void ConsumerSocket::UserOnUnixStreamRead() { MS_TRACE_STD(); @@ -248,34 +292,8 @@ namespace Channel Channel::Request* request{ nullptr }; - try - { - request = new Channel::Request(jsonRequest); - } - catch (const MediaSoupError& error) - { - MS_ERROR_STD("discarding wrong Channel request"); - } - - if (request != nullptr) - { - // Notify the listener. - try - { - this->listener->OnChannelRequest(this, request); - } - catch (const MediaSoupTypeError& error) - { - request->TypeError(error.what()); - } - catch (const MediaSoupError& error) - { - request->Error(error.what()); - } - - // Delete the Request. - delete request; - } + // Notify the listener. + this->listener->OnSocketRequest(this, jsonRequest); } catch (const json::parse_error& error) { @@ -307,12 +325,18 @@ namespace Channel } } - void UnixStreamSocket::UserOnUnixStreamSocketClosed(bool isClosedByPeer) + void ConsumerSocket::UserOnUnixStreamSocketClosed(bool isClosedByPeer) { MS_TRACE_STD(); // Notify the listener. if (isClosedByPeer) - this->listener->OnChannelRemotelyClosed(this); + this->listener->OnSocketRemotelyClosed(this); + } + + ProducerSocket::ProducerSocket(int fd, size_t bufferSize) + : ::UnixStreamSocket(fd, bufferSize, ::UnixStreamSocket::Role::PRODUCER) + { + MS_TRACE_STD(); } } // namespace Channel diff --git a/worker/src/Worker.cpp b/worker/src/Worker.cpp index ee4bf06aff..f6a26ce9d5 100644 --- a/worker/src/Worker.cpp +++ b/worker/src/Worker.cpp @@ -10,13 +10,12 @@ /* Instance methods. */ -Worker::Worker(Channel::ChannelWrapper* channel) : channel(channel) +Worker::Worker(Channel::UnixStreamSocket* channel) : channel(channel) { MS_TRACE(); // Set us as Channel's listener. - this->channel->consumerSocket.SetListener(this); - this->channel->producerSocket.SetListener(this); + this->channel->SetListener(this); // Set the signals handler. this->signalsHandler = new SignalsHandler(this); @@ -119,14 +118,10 @@ RTC::Router* Worker::GetRouterFromRequest(Channel::Request* request) const return router; } -inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* socket, Channel::Request* request) +inline void Worker::OnChannelRequest(Channel::UnixStreamSocket* /*channel*/, Channel::Request* request) { MS_TRACE(); - MS_ASSERT( - socket != &(this->channel->producerSocket), - "Producer Socket should not be used for receiving requests"); - MS_DEBUG_DEV( "Channel request received [method:%s, id:%" PRIu32 "]", request->method.c_str(), request->id); diff --git a/worker/src/main.cpp b/worker/src/main.cpp index 9abe767b2a..21bfef1c72 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -48,11 +48,11 @@ int main(int argc, char* argv[]) DepLibUV::ClassInit(); // Channel socket (it will be handled and deleted by the Worker). - Channel::ChannelWrapper* channel{ nullptr }; + Channel::UnixStreamSocket* channel{ nullptr }; try { - channel = new Channel::ChannelWrapper(ConsumerChannelFd, ProducerChannelFd); + channel = new Channel::UnixStreamSocket(ConsumerChannelFd, ProducerChannelFd); } catch (const MediaSoupError& error) { @@ -62,7 +62,7 @@ int main(int argc, char* argv[]) } // Initialize the Logger. - Logger::ClassInit(&(channel->producerSocket)); + Logger::ClassInit(channel); try { @@ -112,8 +112,7 @@ int main(int argc, char* argv[]) Utils::Crypto::ClassInit(); RTC::DtlsTransport::ClassInit(); RTC::SrtpSession::ClassInit(); - Channel::Notifier::ClassInit(&(channel->producerSocket)); - Channel::Request::ClassInit(&(channel->producerSocket)); + Channel::Notifier::ClassInit(channel); // Ignore some signals. IgnoreSignals(); From d0a9005ff2c62b4c143b3ca753513a3457c65e7f Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Thu, 12 Sep 2019 10:40:14 +0800 Subject: [PATCH 36/41] gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d786e09747..311fec9fb8 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ # Vistual Studio generated Stuff. /worker/**/Debug/ /worker/**/Release/ +/worker/.vs/ # Vistual Studio Code stuff. -/worker/.vs/ +/.vscode/ From 36e2b4c9c063c7addb72a3293e5cde919ef5fe85 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Thu, 12 Sep 2019 10:42:40 +0800 Subject: [PATCH 37/41] code style --- worker/include/Channel/UnixStreamSocket.hpp | 12 +++---- worker/src/Channel/UnixStreamSocket.cpp | 39 +++++++++------------ 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/worker/include/Channel/UnixStreamSocket.hpp b/worker/include/Channel/UnixStreamSocket.hpp index 5df938c1a5..bd3752dc13 100644 --- a/worker/include/Channel/UnixStreamSocket.hpp +++ b/worker/include/Channel/UnixStreamSocket.hpp @@ -14,8 +14,8 @@ namespace Channel class Listener { public: - virtual void OnSocketRequest(::UnixStreamSocket* socket, json& jsonRequest) = 0; - virtual void OnSocketRemotelyClosed(::UnixStreamSocket* socket) = 0; + virtual void OnConsumerSocketMessage(ConsumerSocket* consumerSocket, json& jsonMessage) = 0; + virtual void OnConsumerSocketRemotelyClosed(ConsumerSocket* consumerSocket) = 0; }; public: @@ -65,15 +65,15 @@ namespace Channel void SendLog(char* nsPayload, size_t nsPayloadLen); void SendBinary(const uint8_t* nsPayload, size_t nsPayloadLen); - /* Pure virtual methods inherited from ::ConsumerSocket::Listener. */ + /* Pure virtual methods inherited from ConsumerSocket::Listener. */ public: - void OnSocketRequest(::UnixStreamSocket* socket, json& jsonRequest) override; - void OnSocketRemotelyClosed(::UnixStreamSocket* socket) override; + void OnConsumerSocketMessage(ConsumerSocket* consumerSocket, json& jsonMessage) override; + void OnConsumerSocketRemotelyClosed(ConsumerSocket* consumerSocket) override; private: // Passed by argument. Listener* listener{ nullptr }; - + // Others. ConsumerSocket consumerSocket; ProducerSocket producerSocket; }; diff --git a/worker/src/Channel/UnixStreamSocket.cpp b/worker/src/Channel/UnixStreamSocket.cpp index 16ff043583..e39cb66aa4 100644 --- a/worker/src/Channel/UnixStreamSocket.cpp +++ b/worker/src/Channel/UnixStreamSocket.cpp @@ -36,7 +36,7 @@ namespace Channel void UnixStreamSocket::Send(json& jsonMessage) { - if (producerSocket.IsClosed()) + if (this->producerSocket.IsClosed()) return; std::string nsPayload = jsonMessage.dump(); @@ -68,12 +68,12 @@ namespace Channel nsLen = nsNumLen + nsPayloadLen + 2; - producerSocket.Write(WriteBuffer, nsLen); + this->producerSocket.Write(WriteBuffer, nsLen); } void UnixStreamSocket::SendLog(char* nsPayload, size_t nsPayloadLen) { - if (producerSocket.IsClosed()) + if (this->producerSocket.IsClosed()) return; // MS_TRACE_STD(); @@ -105,12 +105,12 @@ namespace Channel nsLen = nsNumLen + nsPayloadLen + 2; - producerSocket.Write(WriteBuffer, nsLen); + this->producerSocket.Write(WriteBuffer, nsLen); } void UnixStreamSocket::SendBinary(const uint8_t* nsPayload, size_t nsPayloadLen) { - if (producerSocket.IsClosed()) + if (this->producerSocket.IsClosed()) return; size_t nsNumLen; @@ -140,24 +140,15 @@ namespace Channel nsLen = nsNumLen + nsPayloadLen + 2; - producerSocket.Write(WriteBuffer, nsLen); + this->producerSocket.Write(WriteBuffer, nsLen); } - void UnixStreamSocket::OnSocketRequest(::UnixStreamSocket* socket, json& jsonRequest) + void UnixStreamSocket::OnConsumerSocketMessage(ConsumerSocket* consumerSocket, json& jsonMessage) { - Channel::Request* request{ nullptr }; - try { - request = new Channel::Request(this, jsonRequest); - } - catch (const MediaSoupError& error) - { - MS_ERROR_STD("discarding wrong Channel request"); - } + auto* request = new Channel::Request(this, jsonMessage); - if (request != nullptr) - { // Notify the listener. try { @@ -175,9 +166,13 @@ namespace Channel // Delete the Request. delete request; } + catch (const MediaSoupError& error) + { + MS_ERROR_STD("discarding wrong Channel request"); + } } - void UnixStreamSocket::OnSocketRemotelyClosed(::UnixStreamSocket* socket) + void UnixStreamSocket::OnConsumerSocketRemotelyClosed(ConsumerSocket* consumerSocket) { this->listener->OnChannelRemotelyClosed(this); } @@ -288,12 +283,10 @@ namespace Channel try { - json jsonRequest = json::parse(jsonStart, jsonStart + jsonLen); - - Channel::Request* request{ nullptr }; + json jsonMessage = json::parse(jsonStart, jsonStart + jsonLen); // Notify the listener. - this->listener->OnSocketRequest(this, jsonRequest); + this->listener->OnConsumerSocketMessage(this, jsonMessage); } catch (const json::parse_error& error) { @@ -331,7 +324,7 @@ namespace Channel // Notify the listener. if (isClosedByPeer) - this->listener->OnSocketRemotelyClosed(this); + this->listener->OnConsumerSocketRemotelyClosed(this); } ProducerSocket::ProducerSocket(int fd, size_t bufferSize) From bbdae70bd2273b0425fc343d5270c83542357fdc Mon Sep 17 00:00:00 2001 From: tonywu Date: Thu, 12 Sep 2019 11:13:09 +0800 Subject: [PATCH 38/41] add virtual destructor --- worker/include/Channel/UnixStreamSocket.hpp | 1 + worker/src/Channel/UnixStreamSocket.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/worker/include/Channel/UnixStreamSocket.hpp b/worker/include/Channel/UnixStreamSocket.hpp index bd3752dc13..d2d7566fa5 100644 --- a/worker/include/Channel/UnixStreamSocket.hpp +++ b/worker/include/Channel/UnixStreamSocket.hpp @@ -58,6 +58,7 @@ namespace Channel public: explicit UnixStreamSocket(int consumerFd, int producerFd); + virtual ~UnixStreamSocket(); public: void SetListener(Listener* listener); diff --git a/worker/src/Channel/UnixStreamSocket.cpp b/worker/src/Channel/UnixStreamSocket.cpp index e39cb66aa4..0f7f78c044 100644 --- a/worker/src/Channel/UnixStreamSocket.cpp +++ b/worker/src/Channel/UnixStreamSocket.cpp @@ -27,6 +27,11 @@ namespace Channel MS_TRACE_STD(); } + UnixStreamSocket ::~UnixStreamSocket() + { + MS_TRACE(); + } + void UnixStreamSocket::SetListener(Listener* listener) { MS_TRACE_STD(); From 7ac3a9995be7ca3f00070d2b3b7dabdf3385e08e Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 4 Oct 2019 01:41:15 +0800 Subject: [PATCH 39/41] add defines for abseil --- worker/deps/abseil-cpp/abseil-cpp.gyp | 10 ++++++++++ worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/worker/deps/abseil-cpp/abseil-cpp.gyp b/worker/deps/abseil-cpp/abseil-cpp.gyp index df5355a64c..d7ef9046a4 100644 --- a/worker/deps/abseil-cpp/abseil-cpp.gyp +++ b/worker/deps/abseil-cpp/abseil-cpp.gyp @@ -39,6 +39,16 @@ '/wd4068', # unknown pragma '/wd4702' # unreachable code ], + 'defines': [ + 'NOMINMAX', # Don't define min and max macros (windows.h) + # Don't bloat namespace with incompatible winsock versions. + 'WIN32_LEAN_AND_MEAN', + # Don't warn about usage of insecure C functions. + '_CRT_SECURE_NO_WARNINGS', + '_SCL_SECURE_NO_WARNINGS', + # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage + '_ENABLE_EXTENDED_ALIGNED_STORAGE' + ] }] ], }, diff --git a/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp b/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp index df5355a64c..d7ef9046a4 100644 --- a/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp +++ b/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp @@ -39,6 +39,16 @@ '/wd4068', # unknown pragma '/wd4702' # unreachable code ], + 'defines': [ + 'NOMINMAX', # Don't define min and max macros (windows.h) + # Don't bloat namespace with incompatible winsock versions. + 'WIN32_LEAN_AND_MEAN', + # Don't warn about usage of insecure C functions. + '_CRT_SECURE_NO_WARNINGS', + '_SCL_SECURE_NO_WARNINGS', + # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage + '_ENABLE_EXTENDED_ALIGNED_STORAGE' + ] }] ], }, From 461e7a518fc2adef463800b80b16db230eedb533 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Fri, 4 Oct 2019 01:48:48 +0800 Subject: [PATCH 40/41] include --- worker/include/common.hpp | 16 ++++++---------- worker/test/src/Utils/TestIP.cpp | 7 +++++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/worker/include/common.hpp b/worker/include/common.hpp index 0cc5b95ca7..54a9a07eb1 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -1,7 +1,12 @@ #ifndef MS_COMMON_HPP #define MS_COMMON_HPP -#include // std::transform(), std::find(), std::min(), std::max() +#include // std::transform(), std::find(), std::min(), std::max() +#include // PRIu64, etc +#include // size_t +#include // uint8_t, etc +#include // std::function +#include // std::addressof() #ifdef _WIN32 #include // https://stackoverflow.com/a/27443191/2085408 @@ -17,17 +22,8 @@ typedef SSIZE_T ssize_t; #endif #else #include // htonl(), htons(), ntohl(), ntohs() -#include // PRIu64, etc -#include // size_t -#include // uint8_t, etc -#include // std::function -#include // std::addressof() #include // sockaddr_in, sockaddr_in6 #include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 #endif -#include // PRIu64, etc -#include // size_t -#include // uint8_t, etc -#include // std::addressof() #endif diff --git a/worker/test/src/Utils/TestIP.cpp b/worker/test/src/Utils/TestIP.cpp index f5801d7460..6c3e58b745 100644 --- a/worker/test/src/Utils/TestIP.cpp +++ b/worker/test/src/Utils/TestIP.cpp @@ -2,11 +2,14 @@ #include "MediaSoupErrors.hpp" #include "Utils.hpp" #include "catch.hpp" +#include // std::memset() +#ifdef _WIN32 +#include +#else #include // htonl(), htons(), ntohl(), ntohs() -#include // std::memset() #include // sockaddr_in, sockaddr_in6 #include // struct sockaddr, struct sockaddr_storage, AF_INET, AF_INET6 - +#endif using namespace Utils; SCENARIO("Utils::IP::GetFamily()") From 62aeb2950ed95c65849505eebcf546ab0ff86b82 Mon Sep 17 00:00:00 2001 From: HaiYang Wu Date: Sun, 6 Oct 2019 23:14:45 +0800 Subject: [PATCH 41/41] dot at the end of the comment --- worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp | 2 +- worker/include/common.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp b/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp index 955e9ddc15..a2f862711c 100644 --- a/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp +++ b/worker/deps/libwebrtc/deps/abseil-cpp/abseil-cpp.gyp @@ -56,7 +56,7 @@ # Don't warn about usage of insecure C functions. '_CRT_SECURE_NO_WARNINGS', '_SCL_SECURE_NO_WARNINGS', - # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage + # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage. '_ENABLE_EXTENDED_ALIGNED_STORAGE' ] }] diff --git a/worker/include/common.hpp b/worker/include/common.hpp index 54a9a07eb1..c4e0ecc225 100644 --- a/worker/include/common.hpp +++ b/worker/include/common.hpp @@ -12,7 +12,7 @@ // https://stackoverflow.com/a/27443191/2085408 #undef max #undef min -// avoid uv/win.h: error C2628 'intptr_t' followed by 'int' is illegal +// avoid uv/win.h: error C2628 'intptr_t' followed by 'int' is illegal. #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) #include typedef SSIZE_T ssize_t;