Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
2026-04-23 09:27:17 +08:00
44 changed files with 1226 additions and 1077 deletions
+2
View File
@@ -101,6 +101,8 @@ else:
ASFLAGS += ['-no-integrated-as']
elif CONFIG['FFI_TARGET'] == 'AARCH64':
ffi_srcs = ('sysv.S', 'ffi.c')
elif CONFIG['FFI_TARGET'] == 'LOONGARCH64':
ffi_srcs = ('ffi.c', 'sysv.S')
elif CONFIG['FFI_TARGET'] == 'X86':
ffi_srcs = ('ffi.c', 'sysv.S', 'win32.S')
elif CONFIG['FFI_TARGET'] == 'X86_64':
-2
View File
@@ -335,8 +335,6 @@ curses.h
cxxabi.h
DateTimeUtils.h
dbus/dbus.h
dbus/dbus-glib.h
dbus/dbus-glib-lowlevel.h
ddeml.h
Debug.h
dem.h
+7 -6
View File
@@ -400,6 +400,7 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType,
layers::PlanarYCbCrImage* ycbcrImage = static_cast<layers::PlanarYCbCrImage*> (aImage);
gfxImageFormat format = SurfaceFormat::A8R8G8B8_UINT32;
uint32_t stride = GetAlignedStride<16>(aSize.width, 4);
auto size = stride * aSize.height;
size_t length = BufferSizeFromStrideAndHeight(stride, aSize.height);
if (length == 0) {
return NS_ERROR_INVALID_ARG;
@@ -413,10 +414,10 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType,
stride);
rv = aEncoder->InitFromData(data.Elements(),
aSize.width * aSize.height * 4,
size,
aSize.width,
aSize.height,
aSize.width * 4,
stride,
imgIEncoder::INPUT_FORMAT_HOSTARGB,
aOptions);
} else {
@@ -433,10 +434,10 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType,
return NS_ERROR_INVALID_ARG;
}
rv = aEncoder->InitFromData(map.mData,
aSize.width * aSize.height * 4,
map.mStride * aSize.height,
aSize.width,
aSize.height,
aSize.width * 4,
map.mStride,
imgIEncoder::INPUT_FORMAT_HOSTARGB,
aOptions);
dataSurface->Unmap();
@@ -467,10 +468,10 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType,
return NS_ERROR_INVALID_ARG;
}
rv = aEncoder->InitFromData(map.mData,
aSize.width * aSize.height * 4,
map.mStride * aSize.height,
aSize.width,
aSize.height,
aSize.width * 4,
map.mStride,
imgIEncoder::INPUT_FORMAT_HOSTARGB,
aOptions);
emptyCanvas->Unmap();
-2
View File
@@ -77,6 +77,4 @@ if CONFIG['MOZ_GAMEPAD']:
]
CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
+15 -3
View File
@@ -15,6 +15,7 @@
#include "DXVA2Manager.h"
#include "nsThreadUtils.h"
#include "Layers.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/layers/LayersTypes.h"
#include "MediaInfo.h"
@@ -741,6 +742,10 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
stride = mVideoStride;
}
if (stride <= 0) {
LOG("CreateBasicVideoFrame: invalid stride %ld", stride);
return E_FAIL;
}
// YV12, planar format: [YYYY....][VVVV....][UUUU....]
// i.e., Y, then V, then U.
@@ -763,9 +768,16 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
if (videoHeight % 16 != 0) {
padding = 16 - (videoHeight % 16);
}
uint32_t y_size = stride * (videoHeight + padding);
uint32_t v_size = stride * (videoHeight + padding) / 4;
uint32_t halfStride = (stride + 1) / 2;
mozilla::CheckedInt<uint32_t> y_size_checked =
mozilla::CheckedInt<uint32_t>(static_cast<uint32_t>(stride)) *
(videoHeight + padding);
if (!y_size_checked.isValid()) {
LOG("CreateBasicVideoFrame: plane size too large");
return E_FAIL;
}
uint32_t y_size = y_size_checked.value();
uint32_t v_size = y_size / 4;
uint32_t halfStride = static_cast<uint32_t>((static_cast<int64_t>(stride) + 1) / 2);
uint32_t halfHeight = (videoHeight + 1) / 2;
uint32_t halfWidth = (videoWidth + 1) / 2;
+22 -22
View File
@@ -818,13 +818,13 @@ generate_composite_function \
.macro over_white_8888_8888_ca_1pixel_tail
mvn TMP0, WK1
teq WK1, WK1, asr #32
bne 01f
bcc 03f
bne 1f
bcc 3f
mov WK3, WK1
b 02f
01: over_white_8888_8888_ca_combine WK1, WK3
02: pixst , 4, 3, DST
03:
b 2f
1: over_white_8888_8888_ca_combine WK1, WK3
2: pixst , 4, 3, DST
3:
.endm
.macro over_white_8888_8888_ca_2pixels_head
@@ -835,21 +835,21 @@ generate_composite_function \
pixld , 8, 3, DST
mvn TMP0, WK1
teq WK1, WK1, asr #32
bne 01f
bne 1f
movcs WK3, WK1
bcs 02f
bcs 2f
teq WK2, #0
beq 05f
b 02f
01: over_white_8888_8888_ca_combine WK1, WK3
02: mvn TMP0, WK2
beq 5f
b 2f
1: over_white_8888_8888_ca_combine WK1, WK3
2: mvn TMP0, WK2
teq WK2, WK2, asr #32
bne 03f
bne 3f
movcs WK4, WK2
b 04f
03: over_white_8888_8888_ca_combine WK2, WK4
04: pixst , 8, 3, DST
05:
b 4f
3: over_white_8888_8888_ca_combine WK2, WK4
4: pixst , 8, 3, DST
5:
.endm
.macro over_white_8888_8888_ca_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload
@@ -1065,9 +1065,9 @@ generate_composite_function \
.if offset != 0
ldrb ORIG_W, [SRC, #offset]
.endif
beq 01f
beq 1f
teq STRIDE_M, #0xFF
beq 02f
beq 2f
.endif
uxtb16 SCRATCH, d /* rb_dest */
uxtb16 d, d, ror #8 /* ag_dest */
@@ -1077,13 +1077,13 @@ generate_composite_function \
uxtab16 d, d, d, ror #8
mov SCRATCH, SCRATCH, ror #8
sel d, SCRATCH, d
b 02f
b 2f
.if offset == 0
48: /* Last mov d,#0 of the set - used as part of shortcut for
* source values all 0 */
.endif
01: mov d, #0
02:
1: mov d, #0
2:
.endm
.macro in_reverse_8888_8888_tail numbytes, reg1, reg2, reg3, reg4
-2
View File
@@ -99,6 +99,4 @@ if CONFIG['MOZ_GAMEPAD']:
]
CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
-2
View File
@@ -27,6 +27,4 @@ FINAL_LIBRARY = 'xul'
if CONFIG['MOZ_ENABLE_DBUS']:
CFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
+5 -2
View File
@@ -6,7 +6,7 @@
@depends(target)
def force_system_ffi(target):
# Pre-emptively move to system ffi for non-tier one platforms.
if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64'):
if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64', 'loongarch64'):
return True
imply_option('--with-system-ffi', force_system_ffi, "target")
@@ -27,7 +27,7 @@ add_old_configure_assignment('MOZ_SYSTEM_FFI', depends_if(system_ffi)(lambda _:
# Target selection, based on ffi/configure.ac.
@depends_when(target, when=building_ffi)
def ffi_target(target):
if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64'):
if target.cpu not in ('x86', 'x86_64', 'arm', 'aarch64', 'loongarch64'):
die('Building libffi from the tree is not supported on this platform. '
'Use --with-system-ffi instead.')
@@ -50,6 +50,9 @@ def ffi_target(target):
elif target.cpu == 'aarch64':
target_dir = 'aarch64'
target_name = 'AARCH64'
elif target.cpu == 'loongarch64':
target_dir = 'loongarch64'
target_name = 'LOONGARCH64'
else:
target_dir = 'x86'
target_name = target.cpu.upper()
+600
View File
@@ -0,0 +1,600 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>
2022 Cheng Lulu <chenglulu@loongson.cn>
Based on RISC-V port
LoongArch Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#include <stdint.h>
#if defined(__loongarch_soft_float)
# define ABI_FRLEN 0
#elif defined(__loongarch_single_float)
# define ABI_FRLEN 32
# define ABI_FLOAT float
#elif defined(__loongarch_double_float)
# define ABI_FRLEN 64
# define ABI_FLOAT double
#else
#error unsupported LoongArch floating-point ABI
#endif
#define NARGREG 8
#define STKALIGN 16
#define MAXCOPYARG (2 * sizeof (double))
/* call_context registers
- 8 floating point parameter/result registers.
- 8 integer parameter/result registers.
- 2 registers used by the assembly code to in-place construct its own
stack frame
- frame register
- return register
*/
typedef struct call_context
{
ABI_FLOAT fa[8];
size_t a[10];
} call_context;
typedef struct call_builder
{
call_context *aregs;
int used_integer;
int used_float;
size_t *used_stack;
size_t *stack;
size_t next_struct_area;
} call_builder;
/* Integer (not pointer) less than ABI GRLEN. */
/* FFI_TYPE_INT does not appear to be used. */
#if __SIZEOF_POINTER__ == 8
# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)
#else
# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)
#endif
#if ABI_FRLEN
typedef struct float_struct_info
{
char as_elements;
char type1;
char offset2;
char type2;
} float_struct_info;
#if ABI_FRLEN >= 64
# define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE)
#else
# define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT)
#endif
static ffi_type **
flatten_struct (ffi_type *in, ffi_type **out, ffi_type **out_end)
{
int i;
if (out == out_end)
return out;
if (in->type != FFI_TYPE_STRUCT)
*(out++) = in;
else
for (i = 0; in->elements[i]; i++)
out = flatten_struct (in->elements[i], out, out_end);
return out;
}
/* Structs with at most two fields after flattening, one of which is of
floating point type, are passed in multiple registers if sufficient
registers are available. */
static float_struct_info
struct_passed_as_elements (call_builder *cb, ffi_type *top)
{
float_struct_info ret = {0, 0, 0, 0};
ffi_type *fields[3];
int num_floats, num_ints;
int num_fields = flatten_struct (top, fields, fields + 3) - fields;
if (num_fields == 1)
{
if (IS_FLOAT (fields[0]->type))
{
ret.as_elements = 1;
ret.type1 = fields[0]->type;
}
}
else if (num_fields == 2)
{
num_floats = IS_FLOAT (fields[0]->type) + IS_FLOAT (fields[1]->type);
num_ints = IS_INT (fields[0]->type) + IS_INT (fields[1]->type);
if (num_floats == 0 || num_floats + num_ints != 2)
return ret;
if (cb->used_float + num_floats > NARGREG
|| cb->used_integer + (2 - num_floats) > NARGREG)
return ret;
if (!IS_FLOAT (fields[0]->type) && !IS_FLOAT (fields[1]->type))
return ret;
ret.type1 = fields[0]->type;
ret.type2 = fields[1]->type;
ret.offset2 = ALIGN (fields[0]->size, fields[1]->alignment);
ret.as_elements = 1;
}
return ret;
}
#endif
/* Allocates a single register, float register, or GRLEN-sized stack slot to a
datum. */
static void
marshal_atom (call_builder *cb, int type, void *data)
{
size_t value = 0;
switch (type)
{
case FFI_TYPE_UINT8:
value = *(uint8_t *) data;
break;
case FFI_TYPE_SINT8:
value = *(int8_t *) data;
break;
case FFI_TYPE_UINT16:
value = *(uint16_t *) data;
break;
case FFI_TYPE_SINT16:
value = *(int16_t *) data;
break;
/* 32-bit quantities are always sign-extended in the ABI. */
case FFI_TYPE_UINT32:
value = *(int32_t *) data;
break;
case FFI_TYPE_SINT32:
value = *(int32_t *) data;
break;
#if __SIZEOF_POINTER__ == 8
case FFI_TYPE_UINT64:
value = *(uint64_t *) data;
break;
case FFI_TYPE_SINT64:
value = *(int64_t *) data;
break;
#endif
case FFI_TYPE_POINTER:
value = *(size_t *) data;
break;
#if ABI_FRLEN >= 32
case FFI_TYPE_FLOAT:
*(float *)(cb->aregs->fa + cb->used_float++) = *(float *) data;
return;
#endif
#if ABI_FRLEN >= 64
case FFI_TYPE_DOUBLE:
(cb->aregs->fa[cb->used_float++]) = *(double *) data;
return;
#endif
default:
FFI_ASSERT (0);
break;
}
if (cb->used_integer == NARGREG)
*cb->used_stack++ = value;
else
cb->aregs->a[cb->used_integer++] = value;
}
static void
unmarshal_atom (call_builder *cb, int type, void *data)
{
size_t value;
switch (type)
{
#if ABI_FRLEN >= 32
case FFI_TYPE_FLOAT:
*(float *) data = *(float *)(cb->aregs->fa + cb->used_float++);
return;
#endif
#if ABI_FRLEN >= 64
case FFI_TYPE_DOUBLE:
*(double *) data = cb->aregs->fa[cb->used_float++];
return;
#endif
}
if (cb->used_integer == NARGREG)
value = *cb->used_stack++;
else
value = cb->aregs->a[cb->used_integer++];
switch (type)
{
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
#if __SIZEOF_POINTER__ == 8
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
#endif
case FFI_TYPE_POINTER:
*(ffi_arg *)data = value;
break;
default:
FFI_ASSERT (0);
break;
}
}
/* Allocate and copy a structure that is passed by value on the stack and
return a pointer to it. */
static void *
allocate_and_copy_struct_to_stack (call_builder *cb, void *data,
ffi_type *type)
{
size_t dest = cb->next_struct_area - type->size;
dest = ALIGN_DOWN (dest, type->alignment);
cb->next_struct_area = dest;
return memcpy ((char *)cb->stack + dest, data, type->size);
}
/* Adds an argument to a call, or a not by reference return value. */
static void
marshal (call_builder *cb, ffi_type *type, int var, void *data)
{
size_t realign[2];
#if ABI_FRLEN
if (!var && type->type == FFI_TYPE_STRUCT)
{
float_struct_info fsi = struct_passed_as_elements (cb, type);
if (fsi.as_elements)
{
marshal_atom (cb, fsi.type1, data);
if (fsi.offset2)
marshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2);
return;
}
}
if (!var && cb->used_float < NARGREG
&& IS_FLOAT (type->type))
{
marshal_atom (cb, type->type, data);
return;
}
double promoted;
if (var && type->type == FFI_TYPE_FLOAT)
{
/* C standard requires promoting float -> double for variable arg. */
promoted = *(float *) data;
type = &ffi_type_double;
data = &promoted;
}
#endif
if (type->size > 2 * __SIZEOF_POINTER__)
/* Pass by reference. */
{
allocate_and_copy_struct_to_stack (cb, data, type);
data = (char *)cb->stack + cb->next_struct_area;
marshal_atom (cb, FFI_TYPE_POINTER, &data);
}
else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER)
marshal_atom (cb, type->type, data);
else
{
/* Overlong integers, soft-float floats, and structs without special
float handling are treated identically from this point on. */
/* Variadics are aligned even in registers. */
if (type->alignment > __SIZEOF_POINTER__)
{
if (var)
cb->used_integer = ALIGN (cb->used_integer, 2);
cb->used_stack
= (size_t *) ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__);
}
memcpy (realign, data, type->size);
if (type->size > 0)
marshal_atom (cb, FFI_TYPE_POINTER, realign);
if (type->size > __SIZEOF_POINTER__)
marshal_atom (cb, FFI_TYPE_POINTER, realign + 1);
}
}
/* For arguments passed by reference returns the pointer, otherwise the arg
is copied (up to MAXCOPYARG bytes). */
static void *
unmarshal (call_builder *cb, ffi_type *type, int var, void *data)
{
size_t realign[2];
void *pointer;
#if ABI_FRLEN
if (!var && type->type == FFI_TYPE_STRUCT)
{
float_struct_info fsi = struct_passed_as_elements (cb, type);
if (fsi.as_elements)
{
unmarshal_atom (cb, fsi.type1, data);
if (fsi.offset2)
unmarshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2);
return data;
}
}
if (!var && cb->used_float < NARGREG
&& IS_FLOAT (type->type))
{
unmarshal_atom (cb, type->type, data);
return data;
}
if (var && type->type == FFI_TYPE_FLOAT)
{
int m = cb->used_integer;
void *promoted
= m < NARGREG ? cb->aregs->a + m : cb->used_stack + m - NARGREG + 1;
*(float *) promoted = *(double *) promoted;
}
#endif
if (type->size > 2 * __SIZEOF_POINTER__)
{
/* Pass by reference. */
unmarshal_atom (cb, FFI_TYPE_POINTER, (char *) &pointer);
return pointer;
}
else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER)
{
unmarshal_atom (cb, type->type, data);
return data;
}
else
{
/* Overlong integers, soft-float floats, and structs without special
float handling are treated identically from this point on. */
/* Variadics are aligned even in registers. */
if (type->alignment > __SIZEOF_POINTER__)
{
if (var)
cb->used_integer = ALIGN (cb->used_integer, 2);
cb->used_stack
= (size_t *) ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__);
}
if (type->size > 0)
unmarshal_atom (cb, FFI_TYPE_POINTER, realign);
if (type->size > __SIZEOF_POINTER__)
unmarshal_atom (cb, FFI_TYPE_POINTER, realign + 1);
memcpy (data, realign, type->size);
return data;
}
}
static int
passed_by_ref (call_builder *cb, ffi_type *type, int var)
{
#if ABI_FRLEN
if (!var && type->type == FFI_TYPE_STRUCT)
{
float_struct_info fsi = struct_passed_as_elements (cb, type);
if (fsi.as_elements)
return 0;
}
#endif
return type->size > 2 * __SIZEOF_POINTER__;
}
/* Perform machine dependent cif processing. */
ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{
cif->loongarch_nfixedargs = cif->nargs;
return FFI_OK;
}
/* Perform machine dependent cif processing when we have a variadic
function. */
ffi_status
ffi_prep_cif_machdep_var (ffi_cif *cif, unsigned int nfixedargs,
unsigned int ntotalargs)
{
cif->loongarch_nfixedargs = nfixedargs;
return FFI_OK;
}
/* Low level routine for calling functions. */
extern void ffi_call_asm (void *stack, struct call_context *regs,
void (*fn) (void), void *closure) FFI_HIDDEN;
static void
ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
void *closure)
{
/* This is a conservative estimate, assuming a complex return value and
that all remaining arguments are long long / __int128 */
size_t arg_bytes = cif->bytes;
size_t rval_bytes = 0;
if (rvalue == NULL && cif->rtype->size > 2 * __SIZEOF_POINTER__)
rval_bytes = ALIGN (cif->rtype->size, STKALIGN);
size_t alloc_size = arg_bytes + rval_bytes + sizeof (call_context);
/* The assembly code will deallocate all stack data at lower addresses
than the argument region, so we need to allocate the frame and the
return value after the arguments in a single allocation. */
/* Argument region must be 16-byte aligned in LP64 ABIs. */
size_t alloc_base = ALIGN (alloca (alloc_size + STKALIGN - 1), STKALIGN);
if (rval_bytes)
rvalue = (void *) (alloc_base + arg_bytes);
call_builder cb;
cb.used_float = cb.used_integer = 0;
cb.aregs = (call_context *) (alloc_base + arg_bytes + rval_bytes);
cb.used_stack = (void *) alloc_base;
cb.stack = (void *) alloc_base;
cb.next_struct_area = arg_bytes;
int return_by_ref = passed_by_ref (&cb, cif->rtype, 0);
if (return_by_ref)
cb.aregs->a[cb.used_integer++] = (size_t)rvalue;
int i;
for (i = 0; i < cif->nargs; i++)
marshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs,
avalue[i]);
ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure);
cb.used_float = cb.used_integer = 0;
if (!return_by_ref && rvalue)
unmarshal (&cb, cif->rtype, 0, rvalue);
}
void
ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
{
ffi_call_int (cif, fn, rvalue, avalue, NULL);
}
void
ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
void *closure)
{
ffi_call_int (cif, fn, rvalue, avalue, closure);
}
extern void ffi_closure_asm (void) FFI_HIDDEN;
ffi_status
ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,
void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data, void *codeloc)
{
uint32_t *tramp = (uint32_t *) &closure->tramp[0];
uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;
if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
return FFI_BAD_ABI;
#if defined(FFI_EXEC_STATIC_TRAMP)
if (ffi_tramp_is_present(closure))
{
ffi_tramp_set_parms (closure->ftramp, ffi_closure_asm, closure);
goto out;
}
#endif
/* Fill the dynamic trampoline. We will call ffi_closure_inner with codeloc,
not closure, but as long as the memory is readable it should work. */
tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */
tramp[1] = 0x28c0418d; /* ld.d $t1, $t0, 16 */
tramp[2] = 0x4c0001a0; /* jirl $zero, $t1, 0 */
tramp[3] = 0x03400000; /* nop */
tramp[4] = fn;
tramp[5] = fn >> 32;
__builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
#if defined(FFI_EXEC_STATIC_TRAMP)
out:
#endif
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
return FFI_OK;
}
/* Called by the assembly code with aregs pointing to saved argument registers
and stack pointing to the stacked arguments. Return values passed in
registers will be reloaded from aregs. */
void FFI_HIDDEN
ffi_closure_inner (ffi_cif *cif,
void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data, size_t *stack, call_context *aregs)
{
void **avalue = alloca (cif->nargs * sizeof (void *));
/* Storage for arguments which will be copied by unmarshal(). We could
theoretically avoid the copies in many cases and use at most 128 bytes
of memory, but allocating disjoint storage for each argument is
simpler. */
char *astorage = alloca (cif->nargs * MAXCOPYARG);
void *rvalue;
call_builder cb;
int return_by_ref;
int i;
cb.aregs = aregs;
cb.used_integer = cb.used_float = 0;
cb.used_stack = stack;
return_by_ref = passed_by_ref (&cb, cif->rtype, 0);
if (return_by_ref)
unmarshal (&cb, &ffi_type_pointer, 0, &rvalue);
else
rvalue = alloca (cif->rtype->size);
for (i = 0; i < cif->nargs; i++)
avalue[i]
= unmarshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs,
astorage + i * MAXCOPYARG);
fun (cif, rvalue, avalue, user_data);
if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID)
{
cb.used_integer = cb.used_float = 0;
marshal (&cb, cif->rtype, 0, rvalue);
}
}
#if defined(FFI_EXEC_STATIC_TRAMP)
void *
ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
{
extern void *trampoline_code_table;
*tramp_size = 16;
/* A mapping size of 64K is chosen to cover the page sizes of 4K, 16K, and
64K. */
*map_size = 1 << 16;
return &trampoline_code_table;
}
#endif
@@ -0,0 +1,81 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>
2022 Cheng Lulu <chenglulu@loongson.cn>
Target configuration macros for LoongArch.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_H
#error \
"Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
#ifndef __loongarch__
#error \
"libffi was configured for a LoongArch target but this does not appear to be a LoongArch compiler."
#endif
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi
{
FFI_FIRST_ABI = 0,
FFI_LP64S,
FFI_LP64F,
FFI_LP64D,
FFI_LAST_ABI,
#if defined(__loongarch64)
#if defined(__loongarch_soft_float)
FFI_DEFAULT_ABI = FFI_LP64S
#elif defined(__loongarch_single_float)
FFI_DEFAULT_ABI = FFI_LP64F
#elif defined(__loongarch_double_float)
FFI_DEFAULT_ABI = FFI_LP64D
#else
#error unsupported LoongArch floating-point ABI
#endif
#else
#error unsupported LoongArch base architecture
#endif
} ffi_abi;
#endif /* LIBFFI_ASM */
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#define FFI_EXTRA_CIF_FIELDS \
unsigned loongarch_nfixedargs; \
unsigned loongarch_unused;
#define FFI_TARGET_SPECIFIC_VARIADIC
#endif
+327
View File
@@ -0,0 +1,327 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>
2022 Cheng Lulu <chenglulu@loongson.cn>
LoongArch Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
/* Define aliases so that we can handle all ABIs uniformly. */
#if __SIZEOF_POINTER__ == 8
# define PTRS 8
# define LARG ld.d
# define SARG st.d
#else
# define PTRS 4
# define LARG ld.w
# define SARG st.w
#endif
#if defined(__loongarch_single_float)
# define FLTS 4
# define FLD fld.w
# define FST fst.w
#elif defined(__loongarch_double_float)
# define FLTS 8
# define FLARG fld.d
# define FSARG fst.d
#elif defined(__loongarch_soft_float)
# define FLTS 0
#else
#error unsupported LoongArch floating-point ABI
#endif
.text
.globl ffi_call_asm
.type ffi_call_asm, @function
.hidden ffi_call_asm
/* struct call_context
{
ABI_FLOAT fa[8];
size_t a[10];
}
- 8 floating point parameter/result registers (fa[0] - fa[7])
- 8 integer parameter/result registers (a[0] - a[7])
- 2 registers used by the assembly code to in-place construct its own stack
frame.
- frame pointer (a[8])
- return address (a[9])
void ffi_call_asm (size_t *stackargs, struct call_context *regargs,
void (*fn)(void), void *closure); */
#define FRAME_LEN (8 * FLTS + 10 * PTRS)
ffi_call_asm:
.cfi_startproc
/* We are NOT going to set up an ordinary stack frame. In order to pass
the stacked args to the called function, we adjust our stack pointer
to a0, which is in the _caller's_ alloca area. We establish our own
stack frame at the end of the call_context.
Anything below the arguments will be freed at this point, although
we preserve the call_context so that it can be read back in the
caller. */
.cfi_def_cfa 5, FRAME_LEN # Interim CFA based on a1.
SARG $fp, $a1, FRAME_LEN - 2*PTRS
.cfi_offset 22, -2*PTRS
SARG $ra, $a1, FRAME_LEN - 1*PTRS
.cfi_offset 1, -1*PTRS
addi.d $fp, $a1, FRAME_LEN
move $sp, $a0
.cfi_def_cfa 22, 0 # Our frame is fully set up.
# Load arguments.
move $t1, $a2
move $t2, $a3
#if FLTS
FLARG $fa0, $fp, -FRAME_LEN+0*FLTS
FLARG $fa1, $fp, -FRAME_LEN+1*FLTS
FLARG $fa2, $fp, -FRAME_LEN+2*FLTS
FLARG $fa3, $fp, -FRAME_LEN+3*FLTS
FLARG $fa4, $fp, -FRAME_LEN+4*FLTS
FLARG $fa5, $fp, -FRAME_LEN+5*FLTS
FLARG $fa6, $fp, -FRAME_LEN+6*FLTS
FLARG $fa7, $fp, -FRAME_LEN+7*FLTS
#endif
LARG $a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS
LARG $a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS
LARG $a2, $fp, -FRAME_LEN+8*FLTS+2*PTRS
LARG $a3, $fp, -FRAME_LEN+8*FLTS+3*PTRS
LARG $a4, $fp, -FRAME_LEN+8*FLTS+4*PTRS
LARG $a5, $fp, -FRAME_LEN+8*FLTS+5*PTRS
LARG $a6, $fp, -FRAME_LEN+8*FLTS+6*PTRS
LARG $a7, $fp, -FRAME_LEN+8*FLTS+7*PTRS
/* Call */
jirl $ra, $t1, 0
#if FLTS
/* Save return values - only a0/a1 (fa0/fa1) are used. */
FSARG $fa0, $fp, -FRAME_LEN+0*FLTS
FSARG $fa1, $fp, -FRAME_LEN+1*FLTS
#endif
SARG $a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS
SARG $a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS
/* Restore and return. */
addi.d $sp, $fp, -FRAME_LEN
.cfi_def_cfa 3, FRAME_LEN
LARG $ra, $fp, -1*PTRS
.cfi_restore 1
LARG $fp, $fp, -2*PTRS
.cfi_restore 22
jr $ra
.cfi_endproc
.size ffi_call_asm, .-ffi_call_asm
/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t0.
void ffi_closure_inner (ffi_cif *cif,
void (*fun)(ffi_cif *, void *, void **, void *),
void *user_data,
size_t *stackargs, struct call_context *regargs) */
.globl ffi_closure_asm
.hidden ffi_closure_asm
.type ffi_closure_asm, @function
ffi_closure_asm:
.cfi_startproc
addi.d $sp, $sp, -FRAME_LEN
.cfi_def_cfa_offset FRAME_LEN
/* Make a frame. */
SARG $fp, $sp, FRAME_LEN - 2*PTRS
.cfi_offset 22, -2*PTRS
SARG $ra, $sp, FRAME_LEN - 1*PTRS
.cfi_offset 1, -1*PTRS
addi.d $fp, $sp, FRAME_LEN
/* Save arguments. */
#if FLTS
FSARG $fa0, $sp, 0*FLTS
FSARG $fa1, $sp, 1*FLTS
FSARG $fa2, $sp, 2*FLTS
FSARG $fa3, $sp, 3*FLTS
FSARG $fa4, $sp, 4*FLTS
FSARG $fa5, $sp, 5*FLTS
FSARG $fa6, $sp, 6*FLTS
FSARG $fa7, $sp, 7*FLTS
#endif
SARG $a0, $sp, 8*FLTS+0*PTRS
SARG $a1, $sp, 8*FLTS+1*PTRS
SARG $a2, $sp, 8*FLTS+2*PTRS
SARG $a3, $sp, 8*FLTS+3*PTRS
SARG $a4, $sp, 8*FLTS+4*PTRS
SARG $a5, $sp, 8*FLTS+5*PTRS
SARG $a6, $sp, 8*FLTS+6*PTRS
SARG $a7, $sp, 8*FLTS+7*PTRS
/* Enter C */
LARG $a0, $t0, FFI_TRAMPOLINE_SIZE+0*PTRS
LARG $a1, $t0, FFI_TRAMPOLINE_SIZE+1*PTRS
LARG $a2, $t0, FFI_TRAMPOLINE_SIZE+2*PTRS
addi.d $a3, $sp, FRAME_LEN
move $a4, $sp
bl ffi_closure_inner
/* Return values. */
#if FLTS
FLARG $fa0, $sp, 0*FLTS
FLARG $fa1, $sp, 1*FLTS
#endif
LARG $a0, $sp, 8*FLTS+0*PTRS
LARG $a1, $sp, 8*FLTS+1*PTRS
/* Restore and return. */
LARG $ra, $sp, FRAME_LEN-1*PTRS
.cfi_restore 1
LARG $fp, $sp, FRAME_LEN-2*PTRS
.cfi_restore 22
addi.d $sp, $sp, FRAME_LEN
.cfi_def_cfa_offset 0
jr $ra
.cfi_endproc
.size ffi_closure_asm, .-ffi_closure_asm
/* Static trampoline code table, in which each element is a trampoline.
The trampoline clobbers t0 and t1, but we don't save them on the stack
because our psABI explicitly says they are scratch registers, at least for
ELF. Our dynamic trampoline is already clobbering them anyway.
The trampoline has two parameters - target code to jump to and data for
the target code. The trampoline extracts the parameters from its parameter
block (see tramp_table_map()). The trampoline saves the data address in
t0 and jumps to the target code. As ffi_closure_asm() already expects the
data address to be in t0, we don't need a "ffi_closure_asm_alt". */
#if defined(FFI_EXEC_STATIC_TRAMP)
.align 16
.globl trampoline_code_table
.hidden trampoline_code_table
.type trampoline_code_table, @function
trampoline_code_table:
.rept 65536 / 16
pcaddu12i $t1, 16 # 65536 >> 12
ld.d $t0, $t1, 0
ld.d $t1, $t1, 8
jirl $zero, $t1, 0
.endr
.size trampoline_code_table, .-trampoline_code_table
.align 2
#endif
/* ffi_go_closure_asm. Expects address of the passed-in ffi_go_closure in t2.
void ffi_closure_inner (ffi_cif *cif,
void (*fun)(ffi_cif *, void *, void **, void *),
void *user_data,
size_t *stackargs, struct call_context *regargs) */
.globl ffi_go_closure_asm
.hidden ffi_go_closure_asm
.type ffi_go_closure_asm, @function
ffi_go_closure_asm:
.cfi_startproc
addi.d $sp, $sp, -FRAME_LEN
.cfi_def_cfa_offset FRAME_LEN
/* Make a frame. */
SARG $fp, $sp, FRAME_LEN - 2*PTRS
.cfi_offset 22, -2*PTRS
SARG $ra, $sp, FRAME_LEN - 1*PTRS
.cfi_offset 1, -1*PTRS
addi.d $fp, $sp, FRAME_LEN
/* Save arguments. */
#if FLTS
FSARG $fa0, $sp, 0*FLTS
FSARG $fa1, $sp, 1*FLTS
FSARG $fa2, $sp, 2*FLTS
FSARG $fa3, $sp, 3*FLTS
FSARG $fa4, $sp, 4*FLTS
FSARG $fa5, $sp, 5*FLTS
FSARG $fa6, $sp, 6*FLTS
FSARG $fa7, $sp, 7*FLTS
#endif
SARG $a0, $sp, 8*FLTS+0*PTRS
SARG $a1, $sp, 8*FLTS+1*PTRS
SARG $a2, $sp, 8*FLTS+2*PTRS
SARG $a3, $sp, 8*FLTS+3*PTRS
SARG $a4, $sp, 8*FLTS+4*PTRS
SARG $a5, $sp, 8*FLTS+5*PTRS
SARG $a6, $sp, 8*FLTS+6*PTRS
SARG $a7, $sp, 8*FLTS+7*PTRS
/* Enter C */
LARG $a0, $t2, 1*PTRS
LARG $a1, $t2, 2*PTRS
move $a2, $t2
addi.d $a3, $sp, FRAME_LEN
move $a4, $sp
bl ffi_closure_inner
/* Return values. */
#if FLTS
FLARG $fa0, $sp, 0*FLTS
FLARG $fa1, $sp, 1*FLTS
#endif
LARG $a0, $sp, 8*FLTS+0*PTRS
LARG $a1, $sp, 8*FLTS+1*PTRS
/* Restore and return. */
LARG $ra, $sp, FRAME_LEN-1*PTRS
.cfi_restore 1
LARG $fp, $sp, FRAME_LEN-2*PTRS
.cfi_restore 22
addi.d $sp, $sp, FRAME_LEN
.cfi_def_cfa_offset 0
jr $ra
.cfi_endproc
.size ffi_go_closure_asm, .-ffi_go_closure_asm
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits
#endif
+70 -43
View File
@@ -860,19 +860,30 @@ GlobalHelperThreadState::waitForAllThreads()
template <typename T>
bool
GlobalHelperThreadState::checkTaskThreadLimit(size_t maxThreads) const
GlobalHelperThreadState::checkTaskThreadLimit(size_t maxThreads, bool isMaster) const
{
if (maxThreads >= threadCount)
return true;
size_t count = 0;
size_t idle = 0;
for (auto& thread : *threads) {
if (thread.currentTask.isSome() && thread.currentTask->is<T>())
count++;
if (thread.currentTask.isSome()) {
if (thread.currentTask->is<T>())
count++;
} else {
idle++;
}
if (count >= maxThreads)
return false;
}
// At least the current thread is idle.
MOZ_ASSERT(idle > 0);
if (isMaster && idle <= 1)
return false;
return true;
}
@@ -916,11 +927,7 @@ GlobalHelperThreadState::maxParseThreads() const
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_PARSE))
return 1;
// Don't allow simultaneous off thread parses, to reduce contention on the
// atoms table. Note that wasm compilation depends on this to avoid
// stalling the helper thread, as off thread parse tasks can trigger and
// block on other off thread wasm compilation tasks.
return 1;
return threadCount;
}
size_t
@@ -1091,7 +1098,8 @@ GlobalHelperThreadState::pendingIonCompileHasSufficientPriority(
bool
GlobalHelperThreadState::canStartParseTask(const AutoLockHelperThreadState& lock)
{
return !parseWorklist(lock).empty() && checkTaskThreadLimit<ParseTask*>(maxParseThreads());
return !parseWorklist(lock).empty() &&
checkTaskThreadLimit<ParseTask*>(maxParseThreads(), /* isMaster = */ true);
}
bool
@@ -1892,49 +1900,68 @@ HelperThread::threadLoop()
while (true) {
MOZ_ASSERT(idle());
// Block until a task is available. Save the value of whether we are
// going to do an Ion compile, in case the value returned by the method
// changes.
bool ionCompile = false;
js::oom::ThreadType task;
while (true) {
if (terminate)
return;
if ((ionCompile = HelperThreadState().pendingIonCompileHasSufficientPriority(lock)) ||
HelperThreadState().canStartWasmCompile(lock) ||
HelperThreadState().canStartPromiseTask(lock) ||
HelperThreadState().canStartParseTask(lock) ||
HelperThreadState().canStartCompressionTask(lock) ||
HelperThreadState().canStartGCHelperTask(lock) ||
HelperThreadState().canStartGCParallelTask(lock))
{
// Select the task type to run. Task priority is determined
// exclusively here.
//
// The selectors may depend on the HelperThreadState not changing
// between task selection and task execution, in particular, on new
// tasks not being added (because of the lifo structure of the work
// lists). Unlocking the HelperThreadState between task selection
// and execution is not well-defined.
if (HelperThreadState().canStartGCParallelTask(lock))
task = js::oom::THREAD_TYPE_GCPARALLEL;
else if (HelperThreadState().canStartGCHelperTask(lock))
task = js::oom::THREAD_TYPE_GCHELPER;
else if (HelperThreadState().pendingIonCompileHasSufficientPriority(lock))
task = js::oom::THREAD_TYPE_ION;
else if (HelperThreadState().canStartWasmCompile(lock))
task = js::oom::THREAD_TYPE_ASMJS;
else if (HelperThreadState().canStartPromiseTask(lock))
task = js::oom::THREAD_TYPE_PROMISE_TASK;
else if (HelperThreadState().canStartParseTask(lock))
task = js::oom::THREAD_TYPE_PARSE;
else if (HelperThreadState().canStartCompressionTask(lock))
task = js::oom::THREAD_TYPE_COMPRESS;
else
task = js::oom::THREAD_TYPE_NONE;
if (task != js::oom::THREAD_TYPE_NONE)
break;
}
HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
}
if (ionCompile) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_ION);
handleIonWorkload(lock);
} else if (HelperThreadState().canStartWasmCompile(lock)) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_ASMJS);
handleWasmWorkload(lock);
} else if (HelperThreadState().canStartPromiseTask(lock)) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_PROMISE_TASK);
handlePromiseTaskWorkload(lock);
} else if (HelperThreadState().canStartParseTask(lock)) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_PARSE);
handleParseWorkload(lock, stackLimit);
} else if (HelperThreadState().canStartCompressionTask(lock)) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_COMPRESS);
handleCompressionWorkload(lock);
} else if (HelperThreadState().canStartGCHelperTask(lock)) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_GCHELPER);
handleGCHelperWorkload(lock);
} else if (HelperThreadState().canStartGCParallelTask(lock)) {
js::oom::SetThreadType(js::oom::THREAD_TYPE_GCPARALLEL);
js::oom::SetThreadType(task);
switch (task) {
case js::oom::THREAD_TYPE_GCPARALLEL:
handleGCParallelWorkload(lock);
} else {
break;
case js::oom::THREAD_TYPE_GCHELPER:
handleGCHelperWorkload(lock);
break;
case js::oom::THREAD_TYPE_ION:
handleIonWorkload(lock);
break;
case js::oom::THREAD_TYPE_ASMJS:
handleWasmWorkload(lock);
break;
case js::oom::THREAD_TYPE_PROMISE_TASK:
handlePromiseTaskWorkload(lock);
break;
case js::oom::THREAD_TYPE_PARSE:
handleParseWorkload(lock, stackLimit);
break;
case js::oom::THREAD_TYPE_COMPRESS:
handleCompressionWorkload(lock);
break;
default:
MOZ_CRASH("No task to perform");
}
js::oom::SetThreadType(js::oom::THREAD_TYPE_NONE);
}
}
+1 -1
View File
@@ -256,7 +256,7 @@ class GlobalHelperThreadState
void waitForAllThreads();
template <typename T>
bool checkTaskThreadLimit(size_t maxThreads) const;
bool checkTaskThreadLimit(size_t maxThreads, bool isMaster = false) const;
private:
@@ -58,7 +58,7 @@ chromeos_dev_list="libbluetooth-dev libpulse-dev"
# Packages need for development
dev_list="apache2.2-bin bison curl elfutils fakeroot flex g++ gperf
language-pack-fr libapache2-mod-php5 libasound2-dev libbz2-dev
libcairo2-dev libcups2-dev libcurl4-gnutls-dev libdbus-glib-1-dev
libcairo2-dev libcups2-dev libcurl4-gnutls-dev
libelf-dev libgconf2-dev libgl1-mesa-dev libglib2.0-dev
libglu1-mesa-dev libgnome-keyring-dev libgtk2.0-dev
libkrb5-dev libnspr4-dev libnss3-dev libpam0g-dev libsctp-dev
@@ -80,7 +80,7 @@ fi
chromeos_lib_list="libpulse0 libbz2-1.0 libcurl4-gnutls-dev"
# Full list of required run-time libraries
lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libdbus-glib-1-2
lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2
libexpat1 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
libgtk2.0-0 libpam0g libpango1.0-0 libpcre3 libpixman-1-0
libpng12-0 libstdc++6 libsqlite3-0 libudev0 libx11-6 libxau6 libxcb1
@@ -89,7 +89,7 @@ lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libdbus-glib-1-2
$chromeos_lib_list"
# Debugging symbols for all of the run-time libraries
dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libdbus-glib-1-2-dbg
dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg
libfontconfig1-dbg libglib2.0-0-dbg libgtk2.0-0-dbg
libpango1.0-0-dbg libpcre3-dbg libpixman-1-0-dbg
libsqlite3-0-dbg
-21
View File
@@ -112,27 +112,6 @@
],
},
], # targets
}, { # chromeos==1
'targets': [
{
# TODO(satorux): Remove this once dbus-glib clients are gone.
'target_name': 'dbus-glib',
'type': 'none',
'direct_dependent_settings': {
'cflags': [
'<!@(<(pkg-config) --cflags dbus-glib-1)',
],
},
'link_settings': {
'ldflags': [
'<!@(<(pkg-config) --libs-only-L --libs-only-other dbus-glib-1)',
],
'libraries': [
'<!@(<(pkg-config) --libs-only-l dbus-glib-1)',
],
},
},
],
}]
], # conditions
'targets': [
-16
View File
@@ -61,12 +61,6 @@ config("common_inherited_config") {
}
}
if (rtc_have_dbus_glib) {
pkg_config("dbus-glib") {
packages = [ "dbus-glib-1" ]
}
}
config("common_config") {
cflags = []
cflags_cc = []
@@ -74,16 +68,6 @@ config("common_config") {
defines = [ "WEBRTC_RESTRICT_LOGGING" ]
}
if (rtc_have_dbus_glib) {
defines += [ "HAVE_DBUS_GLIB" ]
# TODO(kjellander): Investigate this, it seems like include <dbus/dbus.h>
# is still not found even if the execution of
# build/config/linux/pkg-config.py dbus-glib-1 returns correct include
# dirs on Linux.
all_dependent_configs = [ "dbus-glib" ]
}
if (build_with_chromium) {
defines += [ "LOGGING_INSIDE_WEBRTC" ]
} else {
-4
View File
@@ -426,10 +426,6 @@ static_library("rtc_base") {
if (is_linux) {
sources += [
"dbus.cc",
"dbus.h",
"libdbusglibsymboltable.cc",
"libdbusglibsymboltable.h",
"linuxfdwalk.c",
"linuxfdwalk.h",
]
-12
View File
@@ -204,8 +204,6 @@
'crc32.h',
'cryptstring.cc',
'cryptstring.h',
'dbus.cc',
'dbus.h',
'diskcache.cc',
'diskcache.h',
'diskcache_win32.cc',
@@ -246,8 +244,6 @@
'json.h',
'latebindingsymboltable.cc',
'latebindingsymboltable.h',
'libdbusglibsymboltable.cc',
'libdbusglibsymboltable.h',
'linux.cc',
'linux.h',
'linuxfdwalk.c',
@@ -456,8 +452,6 @@
'bandwidthsmoother.h',
'bind.h',
'callback.h',
'dbus.cc',
'dbus.h',
'diskcache_win32.cc',
'diskcache_win32.h',
'fileutils_mock.h',
@@ -468,8 +462,6 @@
'json.h',
'latebindingsymboltable.cc',
'latebindingsymboltable.h',
'libdbusglibsymboltable.cc',
'libdbusglibsymboltable.h',
'linuxfdwalk.c',
'linuxfdwalk.h',
'x11windowpicker.cc',
@@ -627,10 +619,6 @@
},
}, {
'sources!': [
'dbus.cc',
'dbus.h',
'libdbusglibsymboltable.cc',
'libdbusglibsymboltable.h',
'linuxfdwalk.c',
],
}],
-400
View File
@@ -1,400 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifdef HAVE_DBUS_GLIB
#include "webrtc/base/dbus.h"
#include <glib.h>
#include "webrtc/base/logging.h"
#include "webrtc/base/thread.h"
namespace rtc {
// Avoid static object construction/destruction on startup/shutdown.
static pthread_once_t g_dbus_init_once = PTHREAD_ONCE_INIT;
static LibDBusGlibSymbolTable *g_dbus_symbol = NULL;
// Releases DBus-Glib symbols.
static void ReleaseDBusGlibSymbol() {
if (g_dbus_symbol != NULL) {
delete g_dbus_symbol;
g_dbus_symbol = NULL;
}
}
// Loads DBus-Glib symbols.
static void InitializeDBusGlibSymbol() {
// This is thread safe.
if (NULL == g_dbus_symbol) {
g_dbus_symbol = new LibDBusGlibSymbolTable();
// Loads dbus-glib
if (NULL == g_dbus_symbol || !g_dbus_symbol->Load()) {
LOG(LS_WARNING) << "Failed to load dbus-glib symbol table.";
ReleaseDBusGlibSymbol();
} else {
// Nothing we can do if atexit() failed. Just ignore its returned value.
atexit(ReleaseDBusGlibSymbol);
}
}
}
inline static LibDBusGlibSymbolTable *GetSymbols() {
return DBusMonitor::GetDBusGlibSymbolTable();
}
// Implementation of class DBusSigMessageData
DBusSigMessageData::DBusSigMessageData(DBusMessage *message)
: TypedMessageData<DBusMessage *>(message) {
GetSymbols()->dbus_message_ref()(data());
}
DBusSigMessageData::~DBusSigMessageData() {
GetSymbols()->dbus_message_unref()(data());
}
// Implementation of class DBusSigFilter
// Builds a DBus filter string from given DBus path, interface and member.
std::string DBusSigFilter::BuildFilterString(const std::string &path,
const std::string &interface,
const std::string &member) {
std::string ret(DBUS_TYPE "='" DBUS_SIGNAL "'");
if (!path.empty()) {
ret += ("," DBUS_PATH "='");
ret += path;
ret += "'";
}
if (!interface.empty()) {
ret += ("," DBUS_INTERFACE "='");
ret += interface;
ret += "'";
}
if (!member.empty()) {
ret += ("," DBUS_MEMBER "='");
ret += member;
ret += "'";
}
return ret;
}
// Forwards the message to the given instance.
DBusHandlerResult DBusSigFilter::DBusCallback(DBusConnection *dbus_conn,
DBusMessage *message,
void *instance) {
ASSERT(instance);
if (instance) {
return static_cast<DBusSigFilter *>(instance)->Callback(message);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
// Posts a message to caller thread.
DBusHandlerResult DBusSigFilter::Callback(DBusMessage *message) {
if (caller_thread_) {
caller_thread_->Post(this, DSM_SIGNAL, new DBusSigMessageData(message));
}
// Don't "eat" the message here. Let it pop up.
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
// From MessageHandler.
void DBusSigFilter::OnMessage(Message *message) {
if (message != NULL && DSM_SIGNAL == message->message_id) {
DBusSigMessageData *msg =
static_cast<DBusSigMessageData *>(message->pdata);
if (msg) {
ProcessSignal(msg->data());
delete msg;
}
}
}
// Definition of private class DBusMonitoringThread.
// It creates a worker-thread to listen signals on DBus. The worker-thread will
// be running in a priate GMainLoop forever until either Stop() has been invoked
// or it hits an error.
class DBusMonitor::DBusMonitoringThread : public rtc::Thread {
public:
explicit DBusMonitoringThread(DBusMonitor *monitor,
GMainContext *context,
GMainLoop *mainloop,
std::vector<DBusSigFilter *> *filter_list)
: monitor_(monitor),
context_(context),
mainloop_(mainloop),
connection_(NULL),
idle_source_(NULL),
filter_list_(filter_list) {
ASSERT(monitor_);
ASSERT(context_);
ASSERT(mainloop_);
ASSERT(filter_list_);
}
virtual ~DBusMonitoringThread() {
Stop();
}
// Override virtual method of Thread. Context: worker-thread.
virtual void Run() {
ASSERT(NULL == connection_);
// Setup DBus connection and start monitoring.
monitor_->OnMonitoringStatusChanged(DMS_INITIALIZING);
if (!Setup()) {
LOG(LS_ERROR) << "DBus monitoring setup failed.";
monitor_->OnMonitoringStatusChanged(DMS_FAILED);
CleanUp();
return;
}
monitor_->OnMonitoringStatusChanged(DMS_RUNNING);
g_main_loop_run(mainloop_);
monitor_->OnMonitoringStatusChanged(DMS_STOPPED);
// Done normally. Clean up DBus connection.
CleanUp();
return;
}
// Override virtual method of Thread. Context: caller-thread.
virtual void Stop() {
ASSERT(NULL == idle_source_);
// Add an idle source and let the gmainloop quit on idle.
idle_source_ = g_idle_source_new();
if (idle_source_) {
g_source_set_callback(idle_source_, &Idle, this, NULL);
g_source_attach(idle_source_, context_);
} else {
LOG(LS_ERROR) << "g_idle_source_new() failed.";
QuitGMainloop(); // Try to quit anyway.
}
Thread::Stop(); // Wait for the thread.
}
private:
// Registers all DBus filters.
void RegisterAllFilters() {
ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()(
connection_));
for (std::vector<DBusSigFilter *>::iterator it = filter_list_->begin();
it != filter_list_->end(); ++it) {
DBusSigFilter *filter = (*it);
if (!filter) {
LOG(LS_ERROR) << "DBusSigFilter list corrupted.";
continue;
}
GetSymbols()->dbus_bus_add_match()(
GetSymbols()->dbus_g_connection_get_connection()(connection_),
filter->filter().c_str(), NULL);
if (!GetSymbols()->dbus_connection_add_filter()(
GetSymbols()->dbus_g_connection_get_connection()(connection_),
&DBusSigFilter::DBusCallback, filter, NULL)) {
LOG(LS_ERROR) << "dbus_connection_add_filter() failed."
<< "Filter: " << filter->filter();
continue;
}
}
}
// Unregisters all DBus filters.
void UnRegisterAllFilters() {
ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()(
connection_));
for (std::vector<DBusSigFilter *>::iterator it = filter_list_->begin();
it != filter_list_->end(); ++it) {
DBusSigFilter *filter = (*it);
if (!filter) {
LOG(LS_ERROR) << "DBusSigFilter list corrupted.";
continue;
}
GetSymbols()->dbus_connection_remove_filter()(
GetSymbols()->dbus_g_connection_get_connection()(connection_),
&DBusSigFilter::DBusCallback, filter);
}
}
// Sets up the monitoring thread.
bool Setup() {
g_main_context_push_thread_default(context_);
// Start connection to dbus.
// If dbus daemon is not running, returns false immediately.
connection_ = GetSymbols()->dbus_g_bus_get_private()(monitor_->type_,
context_, NULL);
if (NULL == connection_) {
LOG(LS_ERROR) << "dbus_g_bus_get_private() unable to get connection.";
return false;
}
if (NULL == GetSymbols()->dbus_g_connection_get_connection()(connection_)) {
LOG(LS_ERROR) << "dbus_g_connection_get_connection() returns NULL. "
<< "DBus daemon is probably not running.";
return false;
}
// Application don't exit if DBus daemon die.
GetSymbols()->dbus_connection_set_exit_on_disconnect()(
GetSymbols()->dbus_g_connection_get_connection()(connection_), FALSE);
// Connect all filters.
RegisterAllFilters();
return true;
}
// Cleans up the monitoring thread.
void CleanUp() {
if (idle_source_) {
// We did an attach() with the GSource, so we need to destroy() it.
g_source_destroy(idle_source_);
// We need to unref() the GSource to end the last reference we got.
g_source_unref(idle_source_);
idle_source_ = NULL;
}
if (connection_) {
if (GetSymbols()->dbus_g_connection_get_connection()(connection_)) {
UnRegisterAllFilters();
GetSymbols()->dbus_connection_close()(
GetSymbols()->dbus_g_connection_get_connection()(connection_));
}
GetSymbols()->dbus_g_connection_unref()(connection_);
connection_ = NULL;
}
g_main_loop_unref(mainloop_);
mainloop_ = NULL;
g_main_context_unref(context_);
context_ = NULL;
}
// Handles callback on Idle. We only add this source when ready to stop.
static gboolean Idle(gpointer data) {
static_cast<DBusMonitoringThread *>(data)->QuitGMainloop();
return TRUE;
}
// We only hit this when ready to quit.
void QuitGMainloop() {
g_main_loop_quit(mainloop_);
}
DBusMonitor *monitor_;
GMainContext *context_;
GMainLoop *mainloop_;
DBusGConnection *connection_;
GSource *idle_source_;
std::vector<DBusSigFilter *> *filter_list_;
};
// Implementation of class DBusMonitor
// Returns DBus-Glib symbol handle. Initialize it first if hasn't.
LibDBusGlibSymbolTable *DBusMonitor::GetDBusGlibSymbolTable() {
// This is multi-thread safe.
pthread_once(&g_dbus_init_once, InitializeDBusGlibSymbol);
return g_dbus_symbol;
};
// Creates an instance of DBusMonitor
DBusMonitor *DBusMonitor::Create(DBusBusType type) {
if (NULL == DBusMonitor::GetDBusGlibSymbolTable()) {
return NULL;
}
return new DBusMonitor(type);
}
DBusMonitor::DBusMonitor(DBusBusType type)
: type_(type),
status_(DMS_NOT_INITIALIZED),
monitoring_thread_(NULL) {
ASSERT(type_ == DBUS_BUS_SYSTEM || type_ == DBUS_BUS_SESSION);
}
DBusMonitor::~DBusMonitor() {
StopMonitoring();
}
bool DBusMonitor::AddFilter(DBusSigFilter *filter) {
if (monitoring_thread_) {
return false;
}
if (!filter) {
return false;
}
filter_list_.push_back(filter);
return true;
}
bool DBusMonitor::StartMonitoring() {
if (!monitoring_thread_) {
g_type_init();
// g_thread_init API is deprecated since glib 2.31.0, see release note:
// http://mail.gnome.org/archives/gnome-announce-list/2011-October/msg00041.html
#if !GLIB_CHECK_VERSION(2, 31, 0)
g_thread_init(NULL);
#endif
GetSymbols()->dbus_g_thread_init()();
GMainContext *context = g_main_context_new();
if (NULL == context) {
LOG(LS_ERROR) << "g_main_context_new() failed.";
return false;
}
GMainLoop *mainloop = g_main_loop_new(context, FALSE);
if (NULL == mainloop) {
LOG(LS_ERROR) << "g_main_loop_new() failed.";
g_main_context_unref(context);
return false;
}
monitoring_thread_ = new DBusMonitoringThread(this, context, mainloop,
&filter_list_);
if (monitoring_thread_ == NULL) {
LOG(LS_ERROR) << "Failed to create DBus monitoring thread.";
g_main_context_unref(context);
g_main_loop_unref(mainloop);
return false;
}
monitoring_thread_->Start();
}
return true;
}
bool DBusMonitor::StopMonitoring() {
if (monitoring_thread_) {
monitoring_thread_->Stop();
monitoring_thread_ = NULL;
}
return true;
}
DBusMonitor::DBusMonitorStatus DBusMonitor::GetStatus() {
return status_;
}
void DBusMonitor::OnMonitoringStatusChanged(DBusMonitorStatus status) {
status_ = status;
}
#undef LATE
} // namespace rtc
#endif // HAVE_DBUS_GLIB
-168
View File
@@ -1,168 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_DBUS_H_
#define WEBRTC_BASE_DBUS_H_
#ifdef HAVE_DBUS_GLIB
#include <dbus/dbus.h>
#include <string>
#include <vector>
#include "webrtc/base/libdbusglibsymboltable.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/thread.h"
namespace rtc {
#define DBUS_TYPE "type"
#define DBUS_SIGNAL "signal"
#define DBUS_PATH "path"
#define DBUS_INTERFACE "interface"
#define DBUS_MEMBER "member"
#ifdef CHROMEOS
#define CROS_PM_PATH "/"
#define CROS_PM_INTERFACE "org.chromium.PowerManager"
#define CROS_SIG_POWERCHANGED "PowerStateChanged"
#define CROS_VALUE_SLEEP "mem"
#define CROS_VALUE_RESUME "on"
#else
#define UP_PATH "/org/freedesktop/UPower"
#define UP_INTERFACE "org.freedesktop.UPower"
#define UP_SIG_SLEEPING "Sleeping"
#define UP_SIG_RESUMING "Resuming"
#endif // CHROMEOS
// Wraps a DBus messages.
class DBusSigMessageData : public TypedMessageData<DBusMessage *> {
public:
explicit DBusSigMessageData(DBusMessage *message);
~DBusSigMessageData();
};
// DBusSigFilter is an abstract class that defines the interface of DBus
// signal handling.
// The subclasses implement ProcessSignal() for various purposes.
// When a DBus signal comes, a DSM_SIGNAL message is posted to the caller thread
// which will then invokes ProcessSignal().
class DBusSigFilter : protected MessageHandler {
public:
enum DBusSigMessage { DSM_SIGNAL };
// This filter string should ususally come from BuildFilterString()
explicit DBusSigFilter(const std::string &filter)
: caller_thread_(Thread::Current()), filter_(filter) {
}
// Builds a DBus monitor filter string from given DBus path, interface, and
// member.
// See http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html
static std::string BuildFilterString(const std::string &path,
const std::string &interface,
const std::string &member);
// Handles callback on DBus messages by DBus system.
static DBusHandlerResult DBusCallback(DBusConnection *dbus_conn,
DBusMessage *message,
void *instance);
// Handles callback on DBus messages to each DBusSigFilter instance.
DBusHandlerResult Callback(DBusMessage *message);
// From MessageHandler.
virtual void OnMessage(Message *message);
// Returns the DBus monitor filter string.
const std::string &filter() const { return filter_; }
private:
// On caller thread.
virtual void ProcessSignal(DBusMessage *message) = 0;
Thread *caller_thread_;
const std::string filter_;
};
// DBusMonitor is a class for DBus signal monitoring.
//
// The caller-thread calls AddFilter() first to add the signals that it wants to
// monitor and then calls StartMonitoring() to start the monitoring.
// This will create a worker-thread which listens on DBus connection and sends
// DBus signals back through the callback.
// The worker-thread will be running forever until either StopMonitoring() is
// called from the caller-thread or the worker-thread hit some error.
//
// Programming model:
// 1. Caller-thread: Creates an object of DBusMonitor.
// 2. Caller-thread: Calls DBusMonitor::AddFilter() one or several times.
// 3. Caller-thread: StartMonitoring().
// ...
// 4. Worker-thread: DBus signal recieved. Post a message to caller-thread.
// 5. Caller-thread: DBusFilterBase::ProcessSignal() is invoked.
// ...
// 6. Caller-thread: StopMonitoring().
//
// Assumption:
// AddFilter(), StartMonitoring(), and StopMonitoring() methods are called by
// a single thread. Hence, there is no need to make them thread safe.
class DBusMonitor {
public:
// Status of DBus monitoring.
enum DBusMonitorStatus {
DMS_NOT_INITIALIZED, // Not initialized.
DMS_INITIALIZING, // Initializing the monitoring thread.
DMS_RUNNING, // Monitoring.
DMS_STOPPED, // Not monitoring. Stopped normally.
DMS_FAILED, // Not monitoring. Failed.
};
// Returns the DBus-Glib symbol table.
// We should only use this function to access DBus-Glib symbols.
static LibDBusGlibSymbolTable *GetDBusGlibSymbolTable();
// Creates an instance of DBusMonitor.
static DBusMonitor *Create(DBusBusType type);
~DBusMonitor();
// Adds a filter to DBusMonitor.
bool AddFilter(DBusSigFilter *filter);
// Starts DBus message monitoring.
bool StartMonitoring();
// Stops DBus message monitoring.
bool StopMonitoring();
// Gets the status of DBus monitoring.
DBusMonitorStatus GetStatus();
private:
// Forward declaration. Defined in the .cc file.
class DBusMonitoringThread;
explicit DBusMonitor(DBusBusType type);
// Updates status_ when monitoring status has changed.
void OnMonitoringStatusChanged(DBusMonitorStatus status);
DBusBusType type_;
DBusMonitorStatus status_;
DBusMonitoringThread *monitoring_thread_;
std::vector<DBusSigFilter *> filter_list_;
};
} // namespace rtc
#endif // HAVE_DBUS_GLIB
#endif // WEBRTC_BASE_DBUS_H_
@@ -1,232 +0,0 @@
/*
* Copyright 2011 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifdef HAVE_DBUS_GLIB
#include "webrtc/base/dbus.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/thread.h"
namespace rtc {
#define SIG_NAME "NameAcquired"
static const uint32_t kTimeoutMs = 5000U;
class DBusSigFilterTest : public DBusSigFilter {
public:
// DBusSigFilterTest listens on DBus service itself for "NameAcquired" signal.
// This signal should be received when the application connects to DBus
// service and gains ownership of a name.
// http://dbus.freedesktop.org/doc/dbus-specification.html
DBusSigFilterTest()
: DBusSigFilter(GetFilter()),
message_received_(false) {
}
bool MessageReceived() {
return message_received_;
}
private:
static std::string GetFilter() {
return rtc::DBusSigFilter::BuildFilterString("", "", SIG_NAME);
}
// Implement virtual method of DBusSigFilter. On caller thread.
virtual void ProcessSignal(DBusMessage *message) {
EXPECT_TRUE(message != NULL);
message_received_ = true;
}
bool message_received_;
};
TEST(DBusMonitorTest, StartStopStartStop) {
DBusSigFilterTest filter;
rtc::scoped_ptr<rtc::DBusMonitor> monitor;
monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor) {
EXPECT_TRUE(monitor->AddFilter(&filter));
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_NOT_INITIALIZED);
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_RUNNING);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
} else {
LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
}
}
// DBusMonitorTest listens on DBus service itself for "NameAcquired" signal.
// This signal should be received when the application connects to DBus
// service and gains ownership of a name.
// This test is to make sure that we capture the "NameAcquired" signal.
TEST(DBusMonitorTest, ReceivedNameAcquiredSignal) {
DBusSigFilterTest filter;
rtc::scoped_ptr<rtc::DBusMonitor> monitor;
monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor) {
EXPECT_TRUE(monitor->AddFilter(&filter));
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter.MessageReceived(), kTimeoutMs);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
} else {
LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
}
}
TEST(DBusMonitorTest, ConcurrentMonitors) {
DBusSigFilterTest filter1;
rtc::scoped_ptr<rtc::DBusMonitor> monitor1;
monitor1.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor1) {
EXPECT_TRUE(monitor1->AddFilter(&filter1));
DBusSigFilterTest filter2;
rtc::scoped_ptr<rtc::DBusMonitor> monitor2;
monitor2.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
EXPECT_TRUE(monitor2->AddFilter(&filter2));
EXPECT_TRUE(monitor1->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor1->GetStatus(), kTimeoutMs);
EXPECT_TRUE(monitor2->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor2->GetStatus(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs);
EXPECT_TRUE(monitor2->StopMonitoring());
EXPECT_EQ(monitor2->GetStatus(), DBusMonitor::DMS_STOPPED);
EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
EXPECT_TRUE(monitor1->StopMonitoring());
EXPECT_EQ(monitor1->GetStatus(), DBusMonitor::DMS_STOPPED);
} else {
LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
}
}
TEST(DBusMonitorTest, ConcurrentFilters) {
DBusSigFilterTest filter1;
DBusSigFilterTest filter2;
rtc::scoped_ptr<rtc::DBusMonitor> monitor;
monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor) {
EXPECT_TRUE(monitor->AddFilter(&filter1));
EXPECT_TRUE(monitor->AddFilter(&filter2));
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
} else {
LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
}
}
TEST(DBusMonitorTest, NoAddFilterIfRunning) {
DBusSigFilterTest filter1;
DBusSigFilterTest filter2;
rtc::scoped_ptr<rtc::DBusMonitor> monitor;
monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor) {
EXPECT_TRUE(monitor->AddFilter(&filter1));
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_FALSE(monitor->AddFilter(&filter2));
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
} else {
LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
}
}
TEST(DBusMonitorTest, AddFilterAfterStop) {
DBusSigFilterTest filter1;
DBusSigFilterTest filter2;
rtc::scoped_ptr<rtc::DBusMonitor> monitor;
monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor) {
EXPECT_TRUE(monitor->AddFilter(&filter1));
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
EXPECT_TRUE(monitor->AddFilter(&filter2));
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs);
EXPECT_TRUE(monitor->StopMonitoring());
EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
} else {
LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
}
}
TEST(DBusMonitorTest, StopRightAfterStart) {
DBusSigFilterTest filter;
rtc::scoped_ptr<rtc::DBusMonitor> monitor;
monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
if (monitor) {
EXPECT_TRUE(monitor->AddFilter(&filter));
EXPECT_TRUE(monitor->StartMonitoring());
EXPECT_TRUE(monitor->StopMonitoring());
// Stop the monitoring thread right after it had been started.
// If the monitoring thread got a chance to receive a DBus signal, it would
// post a message to the main thread and signal the main thread wakeup.
// This message will be cleaned out automatically when the filter get
// destructed. Here we also consume the wakeup signal (if there is one) so
// that the testing (main) thread is reset to a clean state.
rtc::Thread::Current()->ProcessMessages(1);
} else {
LOG(LS_WARNING) << "DBus Monitor not started.";
}
}
TEST(DBusSigFilter, BuildFilterString) {
EXPECT_EQ(DBusSigFilter::BuildFilterString("", "", ""),
(DBUS_TYPE "='" DBUS_SIGNAL "'"));
EXPECT_EQ(DBusSigFilter::BuildFilterString("p", "", ""),
(DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'"));
EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i", ""),
(DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p',"
DBUS_INTERFACE "='i'"));
EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i","m"),
(DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p',"
DBUS_INTERFACE "='i'," DBUS_MEMBER "='m'"));
}
} // namespace rtc
#endif // HAVE_DBUS_GLIB
@@ -1,24 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifdef HAVE_DBUS_GLIB
#include "webrtc/base/libdbusglibsymboltable.h"
namespace rtc {
#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME
#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST
#define LATE_BINDING_SYMBOL_TABLE_DLL_NAME "libdbus-glib-1.so.2"
#include "webrtc/base/latebindingsymboltable.cc.def"
} // namespace rtc
#endif // HAVE_DBUS_GLIB
@@ -1,56 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_
#define WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_
#ifdef HAVE_DBUS_GLIB
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "webrtc/base/latebindingsymboltable.h"
namespace rtc {
#define LIBDBUS_GLIB_CLASS_NAME LibDBusGlibSymbolTable
// The libdbus-glib symbols we need, as an X-Macro list.
// This list must contain precisely every libdbus-glib function that is used in
// dbus.cc.
#define LIBDBUS_GLIB_SYMBOLS_LIST \
X(dbus_bus_add_match) \
X(dbus_connection_add_filter) \
X(dbus_connection_close) \
X(dbus_connection_remove_filter) \
X(dbus_connection_set_exit_on_disconnect) \
X(dbus_g_bus_get) \
X(dbus_g_bus_get_private) \
X(dbus_g_connection_get_connection) \
X(dbus_g_connection_unref) \
X(dbus_g_thread_init) \
X(dbus_message_get_interface) \
X(dbus_message_get_member) \
X(dbus_message_get_path) \
X(dbus_message_get_type) \
X(dbus_message_iter_get_arg_type) \
X(dbus_message_iter_get_basic) \
X(dbus_message_iter_init) \
X(dbus_message_ref) \
X(dbus_message_unref)
#define LATE_BINDING_SYMBOL_TABLE_CLASS_NAME LIBDBUS_GLIB_CLASS_NAME
#define LATE_BINDING_SYMBOL_TABLE_SYMBOLS_LIST LIBDBUS_GLIB_SYMBOLS_LIST
#include "webrtc/base/latebindingsymboltable.h.def"
} // namespace rtc
#endif // HAVE_DBUS_GLIB
#endif // WEBRTC_BASE_LIBDBUSGLIBSYMBOLTABLE_H_
@@ -108,9 +108,6 @@
'build_protobuf%': 1,
'build_ssl%': 1,
# Disable by default
'have_dbus_glib%': 0,
# Make it possible to provide custom locations for some libraries.
'libvpx_dir%': '<(DEPTH)/third_party/libvpx_new',
'libyuv_dir%': '<(DEPTH)/third_party/libyuv',
@@ -237,14 +234,6 @@
'WEBRTC_MOZILLA_BUILD',
],
}],
['have_dbus_glib==1', {
'defines': [
'HAVE_DBUS_GLIB',
],
'cflags': [
'<!@(pkg-config --cflags dbus-glib-1)',
],
}],
['rtc_relative_path==1', {
'defines': ['EXPAT_RELATIVE_PATH',],
}],
@@ -539,4 +528,3 @@
},
}, # target_defaults
}
@@ -44,9 +44,6 @@ declare_args() {
rtc_build_opus = true
rtc_build_ssl = true
# Disable by default.
rtc_have_dbus_glib = false
# Enable to use the Mozilla internal settings.
build_with_mozilla = false
+1 -1
View File
@@ -54,6 +54,6 @@ if CONFIG['NECKO_WIFI_DBUS']:
CXXFLAGS += ['-Wno-error=shadow']
if CONFIG['NECKO_WIFI_DBUS']:
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
FINAL_LIBRARY = 'xul'
-1
View File
@@ -2409,7 +2409,6 @@ then
if test "$MOZ_ENABLE_DBUS"
then
PKG_CHECK_MODULES(MOZ_DBUS, dbus-1 >= $DBUS_VERSION)
PKG_CHECK_MODULES(MOZ_DBUS_GLIB, dbus-glib-1 >= $DBUS_VERSION)
AC_DEFINE(MOZ_ENABLE_DBUS)
fi
fi
@@ -2082,6 +2082,45 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
},
// Wildcard SANs have subtle outcomes.
{ ByteString(), DNSName("*.example.com"),
GeneralSubtree(DNSName(".example.com")),
Success,
Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
{ ByteString(), DNSName("*.example.com"),
GeneralSubtree(DNSName("example.com")),
Success,
Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
// A certificate with a wildcard SAN entry like `*.example.com` can't be
// issued by a CA with a DNSName name constraint entry like `foo.example.com`
// in either the permitted or excluded subtrees. If in the permitted subtree,
// the certificate would be valid for `bar.example.com`, which would violate
// the constraint. If in the excluded subtree, the certificate would be valid
// for `foo.example.com`, which would violate the constraint.
{ ByteString(), DNSName("*.example.com"),
GeneralSubtree(DNSName("foo.example.com")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE,
Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
{ ByteString(), DNSName("*.foo.example.com"),
GeneralSubtree(DNSName("example.com")),
Success,
Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
{ ByteString(), DNSName("*.example.com"),
GeneralSubtree(DNSName("foo.example.org")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE,
Success
},
// `*invalid.example.com` is an invalid presented DNSID.
{ ByteString(), DNSName("*invalid.example.com"),
GeneralSubtree(DNSName("invalid.example.com")),
Result::ERROR_BAD_DER,
Result::ERROR_BAD_DER
},
/////////////////////////////////////////////////////////////////////////////
// Basic IP Address constraints (non-CN-ID)
+45 -23
View File
@@ -7,6 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Copyright 2014 Mozilla Contributors
* Copyright 2026 Moonchild Productions
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -170,6 +171,12 @@ enum class IDRole
NameConstraint = 2,
};
enum class NameConstraintsSubtrees : uint8_t
{
permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1
};
enum class AllowWildcards { No = 0, Yes = 1 };
// DNSName constraints implicitly allow subdomain matching when there is no
@@ -182,16 +189,22 @@ enum class AllowDotlessSubdomainMatches { No = 0, Yes = 1 };
bool IsValidDNSID(Input hostname, IDRole idRole,
AllowWildcards allowWildcards);
// `subtreesType` is relevant only when `referenceDNSIDRole` is
// `IDRole::NameConstraint`.
Result MatchPresentedDNSIDWithReferenceDNSID(
Input presentedDNSID,
AllowWildcards allowWildcards,
AllowDotlessSubdomainMatches allowDotlessSubdomainMatches,
IDRole referenceDNSIDRole,
/*optional*/ const NameConstraintsSubtrees* subtreesType,
Input referenceDNSID,
/*out*/ bool& matches);
// `subtreesType` is relevant only when `referenceDNSIDRole` is
// `IDRole::NameConstraint`.
Result MatchPresentedRFC822NameWithReferenceRFC822Name(
Input presentedRFC822Name, IDRole referenceRFC822NameRole,
/*optional*/ const NameConstraintsSubtrees* subtreesType,
Input referenceRFC822Name, /*out*/ bool& matches);
} // namespace
@@ -210,7 +223,7 @@ MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID,
return MatchPresentedDNSIDWithReferenceDNSID(
presentedDNSID, AllowWildcards::Yes,
AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID,
referenceDNSID, matches);
nullptr, referenceDNSID, matches);
}
// Verify that the given end-entity cert, which is assumed to have been already
@@ -694,7 +707,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
rv = MatchPresentedDNSIDWithReferenceDNSID(
presentedID, AllowWildcards::Yes,
AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID,
referenceID, foundMatch);
nullptr, referenceID, foundMatch);
break;
case GeneralNameType::iPAddress:
@@ -704,7 +717,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
case GeneralNameType::rfc822Name:
rv = MatchPresentedRFC822NameWithReferenceRFC822Name(
presentedID, IDRole::ReferenceID, referenceID, foundMatch);
presentedID, IDRole::ReferenceID, nullptr, referenceID, foundMatch);
break;
case GeneralNameType::directoryName:
@@ -730,12 +743,6 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
return Success;
}
enum class NameConstraintsSubtrees : uint8_t
{
permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1
};
Result CheckPresentedIDConformsToNameConstraintsSubtrees(
GeneralNameType presentedIDType,
Input presentedID,
@@ -849,7 +856,7 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
rv = MatchPresentedDNSIDWithReferenceDNSID(
presentedID, AllowWildcards::Yes,
AllowDotlessSubdomainMatches::Yes, IDRole::NameConstraint,
base, matches);
&subtreesType, base, matches);
if (rv != Success) {
return rv;
}
@@ -874,7 +881,7 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
case GeneralNameType::rfc822Name:
rv = MatchPresentedRFC822NameWithReferenceRFC822Name(
presentedID, IDRole::NameConstraint, base, matches);
presentedID, IDRole::NameConstraint, &subtreesType, base, matches);
if (rv != Success) {
return rv;
}
@@ -1057,6 +1064,7 @@ MatchPresentedDNSIDWithReferenceDNSID(
AllowWildcards allowWildcards,
AllowDotlessSubdomainMatches allowDotlessSubdomainMatches,
IDRole referenceDNSIDRole,
/*optional*/ const NameConstraintsSubtrees* subtreesType,
Input referenceDNSID,
/*out*/ bool& matches)
{
@@ -1147,18 +1155,28 @@ MatchPresentedDNSIDWithReferenceDNSID(
return NotReached("Skipping '*' failed",
Result::FATAL_ERROR_LIBRARY_FAILURE);
}
do {
// This will happen if reference is a single, relative label
if (reference.AtEnd()) {
matches = false;
return Success;
}
uint8_t referenceByte;
if (reference.Read(referenceByte) != Success) {
return NotReached("invalid reference ID",
Result::FATAL_ERROR_INVALID_ARGS);
}
} while (!reference.Peek('.'));
// For the permittedSubtrees of a name constraint, wildcard presented
// DNSIDs of the form `*.example.com` only match if the name constraint is
// of the form `.example.com` or `example.com`. To put it another way, a
// permittedSubtrees of `foo.example.com` does not match a wildcard
// presented DNSID of `*.example.com`, because in that case, the
// certificate could be valid for `bar.example.com`, which does not match
// the name constraint.
if (referenceDNSIDRole != IDRole::NameConstraint ||
(subtreesType && *subtreesType != NameConstraintsSubtrees::permittedSubtrees)) {
do {
// This will happen if reference is a single, relative label
if (reference.AtEnd()) {
matches = false;
return Success;
}
uint8_t referenceByte;
if (reference.Read(referenceByte) != Success) {
return NotReached("invalid reference ID",
Result::FATAL_ERROR_INVALID_ARGS);
}
} while (!reference.Peek('.'));
}
}
for (;;) {
@@ -1515,9 +1533,12 @@ IsValidRFC822Name(Input input)
}
}
// `subtreesType` is relevant only when `referenceRFC822NameRole` is
// `IDRole::NameConstraint`.
Result
MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name,
IDRole referenceRFC822NameRole,
/*optional*/ const NameConstraintsSubtrees* subtreesType,
Input referenceRFC822Name,
/*out*/ bool& matches)
{
@@ -1562,6 +1583,7 @@ MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name,
return MatchPresentedDNSIDWithReferenceDNSID(
presentedDNSID, AllowWildcards::No,
AllowDotlessSubdomainMatches::No, IDRole::NameConstraint,
subtreesType,
referenceRFC822Name, matches);
}
}
-1
View File
@@ -44,7 +44,6 @@ RUN apt-get update && apt-get install -y --force-yes \
libcanberra-pulse \
libcurl4-openssl-dev \
libdbus-1-dev \
libdbus-glib-1-dev \
libdrm-intel1:i386 \
libdrm-nouveau1a:i386 \
libdrm-radeon1:i386 \
@@ -50,10 +50,6 @@ install check-devel.i686
install check-devel.x86_64
install check.i686
install check.x86_64
install dbus-glib-devel.i686
install dbus-glib-devel.x86_64
install dbus-glib.i686
install dbus-glib.x86_64
install fontconfig-devel.i686
install fontconfig-devel.x86_64
install fontconfig.i686
@@ -29,7 +29,6 @@ parts:
source: source
stage-packages:
- libxt6
- libdbus-glib-1-2
- libasound2
- libpulse0
- libgl1-mesa-dri
@@ -44,7 +44,6 @@ apt_packages+=('libasound2-plugins:i386')
apt_packages+=('libcanberra-pulse')
apt_packages+=('libcurl4-openssl-dev')
apt_packages+=('libdbus-1-dev')
apt_packages+=('libdbus-glib-1-dev')
apt_packages+=('libdrm-intel1:i386')
apt_packages+=('libdrm-nouveau1a:i386')
apt_packages+=('libdrm-radeon1:i386')
@@ -37,7 +37,6 @@ apt_packages+=('libasound2-dev')
apt_packages+=('libcanberra-pulse')
apt_packages+=('libcurl4-openssl-dev')
apt_packages+=('libdbus-1-dev')
apt_packages+=('libdbus-glib-1-dev')
apt_packages+=('libgconf2-dev')
apt_packages+=('libgstreamer-plugins-base0.10-dev')
apt_packages+=('libgstreamer0.10-dev')
@@ -134,7 +134,7 @@ config = {
# -devel packages dependencies. So manually install the dependencies
# of the above packages.
'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686',
'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686',
'check-devel.i686', 'dbus-devel.i686',
'fontconfig-devel.i686', 'glib2-devel.i686',
'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686',
'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686',
@@ -90,7 +90,7 @@ config = {
# -devel packages dependencies. So manually install the dependencies
# of the above packages.
'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686',
'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686',
'check-devel.i686', 'dbus-devel.i686',
'fontconfig-devel.i686', 'glib2-devel.i686',
'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686',
'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686',
@@ -96,7 +96,7 @@ config = {
# -devel packages dependencies. So manually install the dependencies
# of the above packages.
'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686',
'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686',
'check-devel.i686', 'dbus-devel.i686',
'fontconfig-devel.i686', 'glib2-devel.i686',
'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686',
'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686',
+1 -1
View File
@@ -58,7 +58,7 @@ config = {
"gmp-devel", "nspr", "nspr-devel",
# For building the browser
"dbus-devel", "dbus-glib-devel", "hal-devel",
"dbus-devel", "hal-devel",
"libICE-devel", "libIDL-devel",
# For mach resource-usage
@@ -92,7 +92,7 @@ config = {
# -devel packages dependencies. So manually install the dependencies
# of the above packages.
'ORBit2-devel.i686', 'atk-devel.i686', 'cairo-devel.i686',
'check-devel.i686', 'dbus-devel.i686', 'dbus-glib-devel.i686',
'check-devel.i686', 'dbus-devel.i686',
'fontconfig-devel.i686', 'glib2-devel.i686',
'hal-devel.i686', 'libICE-devel.i686', 'libIDL-devel.i686',
'libSM-devel.i686', 'libXau-devel.i686', 'libXcomposite-devel.i686',
+1 -1
View File
@@ -218,7 +218,7 @@ if CONFIG['MOZ_SNDIO']:
]
if CONFIG['MOZ_ENABLE_DBUS']:
OS_LIBS += CONFIG['MOZ_DBUS_GLIB_LIBS']
OS_LIBS += CONFIG['MOZ_DBUS_LIBS']
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
-1
View File
@@ -134,7 +134,6 @@ if CONFIG['MOZ_ENABLE_XREMOTE']:
CXXFLAGS += CONFIG['TK_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS']
-1
View File
@@ -122,4 +122,3 @@ if CONFIG['MOZ_ENABLE_DBUS']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
CXXFLAGS += CONFIG['TK_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
+2
View File
@@ -3020,6 +3020,7 @@ nsLocalFile::IsExecutable(bool* aResult)
"air", // Adobe AIR installer
"app", // executable application
"application", // from bug 348763
"appref-ms", // ClickOnce link
"appx",
"appxbundle",
"asp",
@@ -3080,6 +3081,7 @@ nsLocalFile::IsExecutable(bool* aResult)
"scf", // Windows explorer command
"scr",
"sct",
"search-ms", // Windows Saved Search
"settingcontent-ms",
"shb",
"shs",